multithreading - Preventing interleaving in C++ -
consider following example class, allows 1 thread wait signal thread.
class sync { std::mutex mtx, access; std::condition_variable cv; bool waiting; public: sync() : waiting(false) { } sync(const sync&); ~sync() { sendsignal(); } void waitforsignal() { access.lock(); if (!waiting) { std::unique_lock<std::mutex> lck (mtx); waiting = true; access.unlock(); // in time between these 2 statements, 'sendsignal()' acquires // lock , calls 'cv.notify_all()', signal missed. cv.wait(lck); } else access.unlock(); } void sendsignal() { access.lock(); if (waiting) { std::unique_lock<std::mutex> lck (mtx); cv.notify_all(); waiting = false; } access.unlock(); } };
the problem i'm having signal missed due interleaving during time between unlocking 'access' mutex , calling 'wait()' on condition_variable. how can prevent this?
you should have 1 mutex. don't see why need access. use mtx protect waiting variable , condition variable.
class sync { std::mutex mtx; std::condition_variable cv; bool waiting; public: sync() : waiting(false) { } sync(const sync&); ~sync() { sendsignal(); } void waitforsignal() { std::unique_lock lck (mtx); if (!waiting) { waiting = true; cv.wait(lck); } } void sendsignal() { std::unique_lock lck (mtx); if (waiting) { cv.notify_all(); waiting = false; } } };
the waiting variable , condition variable state tied should treated single critical section.
Comments
Post a Comment