How do I build a lockless queue?

前端 未结 5 1704
情歌与酒
情歌与酒 2020-12-25 08:41

I\'ve spent today looking into lockless queues. I have a multiple producer, multiple consumer situation. I implemented, for testing, a system using the Interlocked SList t

5条回答
  •  滥情空心
    2020-12-25 09:07

    You could probably implement a limited-size queue with least difficulty... I was thinking about it lately and came up with this design, but you can probably find many other interesting ideas: (WARNING: it might have some issues!)

    • the queue is an array of pointers to items
    • you have to manage 2 pointers (head, tail) which work over the queue in the same way as a circular buffer
    • if head == tail, there are no items
    • if you want to enqueue(ptr), Interlocked-Swap tail with NULL (prev_tail is the swapped value)
      • if prev_tail == NULL, try again
      • if prev_tail + 1 (with wraparound) == head, your queue is full
      • otherwise put your ptr in *prev_tail and assign prev_tail+1 to tail (watch out for buffer wrap-around)
    • for dequeue() make a copy tmp_head=head and check tmp_head == tail
      • if it's true, return because the queue is empty
      • if it's false
        • save *tmp_head as ptr
        • do a CAS: compare head with tmp_head swap head with head+1
        • if CAS failed -- start the whole function over
        • if it succeeded -- return ptr

    You can wait on both head and tail CAS operations, but if the queue is not contended, you should succeed the first time, without unnecessary locks.

    Unlimited-size queues are "a bit" harder ;) But you should be able to create a big-enough queue for most needs.

提交回复
热议问题