Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <mutex>
- #include <condition_variable>
- #include <deque>
- class SpScQueue
- {
- std::mutex mutex;
- std::deque<int> queue;
- bool closed = false;
- std::condition_variable cond;
- public:
- void push(int x)
- {
- std::lock_guard<std::mutex> lock{mutex};
- queue.push_back(x);
- cond.notify_one();
- }
- void close()
- {
- std::lock_guard<std::mutex> lock{mutex};
- closed = true;
- cond.notify_all();
- /*
- * Important: The lock guard's destructor will unlock the mutex.
- * As per C++ 32.6.4.2.2 Class mutex [thread.mutex.class] paragraph 2,
- * is is valid for another thread (in this case the consumer) to destroy
- * the mutex before the unlock() returns.
- * Users have to make sure not to access any members after unlocking,
- * for example by moving the notify_all() out of the lock
- */
- }
- // return false if closed and empty
- bool pop(int* out)
- {
- std::unique_lock<std::mutex> lock{mutex};
- while(queue.empty() && ! closed)
- cond.wait(lock);
- if(queue.empty())
- return false;
- *out = queue.front();
- queue.pop_front();
- return true;
- }
- };
- // producer borrows queue
- void producer(SpScQueue* queue)
- {
- for(int i = 0; i < 10; ++i)
- queue->push(i);
- queue->close();
- }
- // consumer holds ownership of queue
- void consumer(std::unique_ptr<SpScQueue>&& queue)
- {
- int x;
- while(queue->pop(&x)) {
- // consume value x
- }
- queue.reset(); // delete queue
- }
Advertisement