A bounded multi-producer multi-consumer lock-free queue written in C++11.
MPMCQueue<int> q(10);
auto t1 = std::thread([&] {
int v;
q.pop(v);
std::cout << "t1 " << v << "\n";
});
auto t2 = std::thread([&] {
int v;
q.pop(v);
std::cout << "t2 " << v << "\n";
});
q.push(1);
q.push(2);
t1.join();
t2.join();
-
MPMCQueue<T>(size_t capacity);
Constructs a new
MPMCQueue
holding items of typeT
with capacitycapacity
. -
void emplace(Args &&... args);
Enqueue an item using inplace construction. Blocks if queue is full.
-
bool try_emplace(Args &&... args);
Try to enqueue an item using inplace construction. Returns
true
on success andfalse
if queue is full. -
void pop(T &v);
Dequeue an item by copying or moving the item into
v
. Blocks if queue is empty. -
bool try_pop(T &v);
Try to dequeue an item by copying or moving the item into
v
. Returntrue
on sucess andfalse
if the queue is empty.
All operations except construction and destruction are thread safe.
Enqeue:
- Acquire next write ticket from head.
- Wait for our turn (2 * (ticket / capacity)) to write slot (ticket % capacity).
- Set turn = turn + 1 to inform the readers we are done writing.
Dequeue:
- Acquire next read ticket from tail.
- Wait for our turn (2 * (ticket / capacity) + 1) to read slot (ticket % capacity).
- Set turn = turn + 1 to inform the writers we are done reading.
References:
- Dave Dice. PTLQueue : a scalable bounded-capacity MPMC queue.
- Dmitry Vyukov. Bounded MPMC queue.
- Massimiliano Meneghin et al. Performance evaluation of inter-thread communication mechanisms on multicore/multithreaded architectures.
- Oleksandr Otenko. US 8607249 B2: System and method for efficient concurrent queue implementation.
- Paul E. McKenney. Memory Barriers: a Hardware View for Software Hackers.
Testing lock-free algorithms is hard. I'm using two approaches to test the implementation:
- A single threaded test that the functionality works as intended, including that the element constructor and destructor is invoked correctly.
- A multithreaded fuzz test that all elements are enqueued and dequeued correctly under heavy contention.
TODO
This project was created by Erik Rigtorp <[email protected]>.