Thread-Safe Queue - Two Serious Errors -- Rainer Grimm
In my last post "Monitor Object" I implemented a thread-safe queue. I made two serious errors. Sorry. Today, I will fix these issues.
Thread-Safe Queue - Two Serious Errors
by Rainer Grimm
From the article:
First, I want to show you again the erroneous implementation from my last post to understand the context.
// monitorObject.cpp #include <condition_variable> #include <functional> #include <queue> #include <iostream> #include <mutex> #include <random> #include <thread> class Monitor { public: void lock() const { monitMutex.lock(); } void unlock() const { monitMutex.unlock(); } void notify_one() const noexcept { monitCond.notify_one(); } template <typename Predicate> void wait(Predicate pred) const { // (10) std::unique_lock<std::mutex> monitLock(monitMutex); monitCond.wait(monitLock, pred); } private: mutable std::mutex monitMutex; mutable std::condition_variable monitCond; }; template <typename T> // (1) class ThreadSafeQueue: public Monitor { public: void add(T val){ lock(); myQueue.push(val); // (6) unlock(); notify_one(); } T get(){ wait( [this] { return ! myQueue.empty(); } ); // (2) lock(); auto val = myQueue.front(); // (4) myQueue.pop(); // (5) unlock(); return val; } private: std::queue<T> myQueue; // (3) }; class Dice { public: int operator()(){ return rand(); } private: std::function<int()> rand = std::bind(std::uniform_int_distribution<>(1, 6), std::default_random_engine()); }; int main(){ std::cout << '\n'; constexpr auto NumberThreads = 100; ThreadSafeQueue<int> safeQueue; // (7) auto addLambda = [&safeQueue](int val){ safeQueue.add(val); // (8) std::cout << val << " " << std::this_thread::get_id() << "; "; }; auto getLambda = [&safeQueue]{ safeQueue.get(); }; // (9) std::vector<std::thread> addThreads(NumberThreads); Dice dice; for (auto& thr: addThreads) thr = std::thread(addLambda, dice()); std::vector<std::thread> getThreads(NumberThreads); for (auto& thr: getThreads) thr = std::thread(getLambda); for (auto& thr: addThreads) thr.join(); for (auto& thr: getThreads) thr.join(); std::cout << "\n\n"; }

Registration is now open for CppCon 2023! The conference starts on October 1 and will be held
This article goes over the spicy topic of object ownership. We covered the lifetime quirks, and we found out that manual memory management can be a nightmare, we
Registration is now open for CppCon 2023! The conference starts on October 1 and will be held 
Visual Studio 17.6 comes with new functionality in the Address Sanitizer runtime which provides a new “checked build” for C and C++. This new runtime mode diagnoses and reports hidden memory safety errors, with zero false positives, as your app runs.
Registration is now open for CppCon 2023! The conference starts on October 1 and will be held
Registration is now open for CppCon 2023! The conference starts on October 1 and will be held 