Search code examples
multithreadingc++11boostg++lock-free

Need Memory Barrier When Using boost::lockfree::spsc_queue?


I am looking at Boost's lockfree queue.

When the producer thread pushes data struct T into the buffer, it gets copy (via the copy constructor) into the buffer.

When the consumer thread tries to call consume_one() to read an element in the buffer, it seems like a memory barrier is needed? If not, how is it possible that the change made by producer thread is visible to the consumer thread?

Thanks!


Solution

  • An additional memory barrier is not needed.

    The queue works correctly as indices are read with memory order acquire, and written with release memory order: http://en.cppreference.com/w/cpp/atomic/memory_order

    • Acquire: A load operation with this memory order performs the acquire operation on the affected memory location: prior writes made to other memory locations by the thread that did the release become visible in this thread.
    • Release: A store operation with this memory order performs the release operation: prior writes to other memory locations become visible to the threads that do a consume or an acquire on the same location

    As you can see there is no need to worry about the writes to actual element data either, because the index update (which is done after the copy) happens-before the read.


    As the documented requirements for using SPSC queues clearly states that both the consumer and the producer will always be the same, single, threads, all "local" index manipulation is done with "relaxed" memory order.

    Note that the only operation that deviates from this is reset(), which, being similar to construction/destruction, is not threadsafe.

    For a backgrounder on memory order, I recommend Anthony William's excellent book C++ Concurrency In Action