写一个生产者/单个消费者队列的最有效的方法(Most efficient way of writin

2019-10-16 23:13发布

什么是写一个生产者/消费者队列,其中一个线程是生产者,另一个是消费者的最有效的方式。 在一篇论文中,笔者认为,它需要一个原子操作的元素插入到了辫子,但他没有解释如何。

也是他队列是一个环形队列,如果队列为空,而生产者等待如果队列已满消费者等待的时间。 他怎么会这样实现队列。 通过原子操作,没有他的意思是某种互斥的,或只是一个原子变量。 请注意,他说,一个原子操作。

Answer 1:

如果你有实现无锁队列中没有经验,唯一的答案可以是:最有效的(安全)的方法是使用一个锁,通过并行线程(互斥或COND VAR)提供。

无锁算法通常(但不一定是)给你一点额外的性能,但他们可以去可怕的错误,如果你不知道自己在做什么。

在另一方面,Linux下的phtreads实现尽可能避免了锁,并使用futex时候,它需要(再次, futex是什么,是快,但你应该知道你在做什么)。
这样的队列毫不费力通过每秒十万任务。 这似乎限制,但实际上,如果你需要通过每秒1级千万次的任务,你就错了 。 理想情况下,你将几十可能传递到百元左右的任务每秒上的队列(较少的任务,但更大的工作组)。 你想例如,创建50个任务上一个字节的数据工作的每个数据,而不是2500万级的任务的一半兆字节的工作。

如果你还是坚持给无锁实现一试(可能超出学术兴趣的),您将需要一个原子的比较交换操作(查找对C GCC的文档中的“遗留__sync功能”,用于C ++,你会使用新原子操作)。
请务必在微妙的细节像ABA,为此你通常需要某种指针操作的(存储引用计数最低3位)或者以显式的引用计数双字交换阅读起来。

另外,无锁队列可以只用原子添加或没有任何原子操作都实现(参见“快进队列”如果你有兴趣只是出于好奇),如果你做一些假设。 然而,这些只是工作,如果该假设成立真实的,他们更容易出错,所以最好远离它们。



文章来源: Most efficient way of writing a single producer/single consumer queue
标签: c linux gcc x86-64