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"; }
Add a Comment
Comments are closed.