我今天花了很多时间来研究无锁队列。我有一个多生产者,多个消费者的情况。为了测试,我使用Win32下的Interlocked SList实现了一个系统,它使我基于线程的高度基于任务的代码的性能翻了一番。不幸的是,我希望支持多个平台。在多个平台上联锁本身不是问题,我可以安全地假设我可以毫无问题地互锁。然而,实际的实施失去了我。
最大的问题似乎是您需要保证列表推送/弹出只使用一个互锁呼叫。否则你会留下空间让另一个线程夹入并搞砸了。我不确定微软的实现如何在幕后工作,并希望了解更多。
有人能指出我有用的信息(平台和语言非常相关)吗?
除此之外,我很想知道它是否可以实现无锁向量。这对我来说有很大的用处:) 干杯!
编辑:阅读了草药的DDJ文章后,我可以看到一个减少的锁定队列,它与我已经拥有的非常相似。但是我注意到最后有一些文件可以使用双重比较和交换(DCAS)操作进行真正的无锁队列。有没有人使用cmpxchg8b(或cmpxchg16b)实现队列?
我只是在思考这一点(没有阅读论文),但你可以使用这个系统同时更新头部和尾部指针,从而避免在2个原子操作之间跳过另一个线程的任何问题。但是你仍然需要获得下一个头指针来测试尾部指针,看看你是否刚刚修改了尾部。当另一个线程准备这样做时,你如何避免另一个线程更改此信息?这是如何以无锁方式实现的?或者我最好还是阅读一篇研究论文的难以理解的内容? ;)
答案 0 :(得分:11)
你可能会以最小的难度实现一个有限大小的队列......我最近在想这个并想出了这个设计,但你可能会发现许多其他有趣的想法:(警告:它可能有一些问题! )
head
== tail
,则没有商品enqueue(ptr)
,则互锁交换tail
为NULL(prev_tail
为交换值)
prev_tail == NULL
,请再试一次prev_tail + 1
(包围)== head
,您的队列已满ptr
放入*prev_tail
并将prev_tail+1
分配给tail
(注意缓冲区环绕)dequeue()
制作副本tmp_head = head并检查tmp_head == tail
*tmp_head
保存为ptr
head
与tmp_head
交换head
与head+1
进行比较ptr
您可以等待头部和尾部CAS操作,但如果队列没有争用,您应该第一次成功,没有不必要的锁定。
无限大小的队列“有点”难度;)但是你应该能够为大多数需求创建一个足够大的队列。
答案 1 :(得分:3)
我认为这个主题有一些有趣的讨论here,特别是this thread.
答案 2 :(得分:3)
您可能想看看Herb Sutters实现低锁定队列。
http://www.drdobbs.com/hpc-high-performance-computing/211601363
它确实使用了c ++ 0x atomics但它(应该)很容易用你的特定体系结构原子操作实现(__sync_ *使用GNU,solaris *在solaris等上)。
答案 3 :(得分:2)
These伙计们,也许你可以在那里找到一些灵感。其他有趣的文件是yqueue.hpp和atomic_ptr.hpp
答案 4 :(得分:1)
viraptor解决方案是锁定,没有多个生产者/多个消费者无锁队列算法我知道。