双锁并发队列算法问题

时间:2016-05-21 23:26:54

标签: c++ multithreading concurrency synchronization locking

所以我正在阅读Maged M. Michael和Michael L. Scott撰写的文章Simple, Fast, and Practical Non-Blocking and Blocking Concurrent Queue Algorithms,还有一个我无法得到的小问题:

enter image description here

假设我们有两个并发线程在队列初始化后立即触发。其中一个线程调用enqueue,另一个调用dequeue。是什么阻止他们同时访问虚拟节点的next字段?在dequeue线程写入next线程时,enqueue线程是否可以读取{{1}}字段?他们都使用不同的锁...所以我不明白他们之间的同步..

感谢。

1 个答案:

答案 0 :(得分:2)

enqueue()只操纵尾部,而dequeue()只操纵头部,因此它们不需要使用相同的锁。当head和tail指向同一节点时,有一种特殊情况,即在初始化时创建的“虚拟”节点。并且你是正确的,enqueue()可能正在写入该节点的下一个指针,而dequeue()正试图读取它。

并发读写没有问题。请注意,enqueue()创建一个新节点,并在通过将其写入tail-> next使其可见之前完全初始化该对象。因此,没有其他代码能够在中途初始化状态下看到这个新节点。此外,对指针的读/写是原子的,因此dequeue()不可能获得指针的一半。

所以在你的场景中,enqueue()和dequeue()都被立即调用,有两种可能性:

  • enqueue()写入tail-> next dequeue()从head-> next读取。在这种情况下,dequeue()将看到已入队的节点并将其返回。
  • dequeue()从head->读取,然后enqueue()写入tail-> next。在这种情况下,dequeue()认为队列为空并返回false。