Open hazby2002 opened 7 months ago
I use a semaphore (std::counting_semaphore in c++20 for convenience here) to make sure that the queue is not empty. There is a simple example:
std::counting_semaphore
#include <thread> #include <vector> #include <iostream> #include "rigtorp/MPMCQueue.h" int main() { rigtorp::MPMCQueue<int> queue(2333); std::counting_semaphore<> sem{0}; std::thread reader([&]{ int num = 100000; while (num--) { sem.acquire(); int x; if (!queue.try_pop(x)) { std::cout << queue.size() << "\n"; std::cout << "error\n"; exit(-1); } } }); std::vector<std::thread> writers; for (int i = 0; i < 10; i++) { writers.emplace_back([&] { int num = 10000; while (num--) { queue.push(num); sem.release(); } }); } reader.join(); for (auto& writer : writers) writer.join(); std::cout << "ok\n"; }
The code can print "error". Such result can be reproduced in godbolt.
I think it caused by release-acquire memory order of atomic operations, but I am not sure how to solve it.
I use a semaphore (
std::counting_semaphore
in c++20 for convenience here) to make sure that the queue is not empty. There is a simple example:The code can print "error". Such result can be reproduced in godbolt.
I think it caused by release-acquire memory order of atomic operations, but I am not sure how to solve it.