考虑以下示例类,它允许一个线程等待来自另一个线程的信号。
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 the time between these two statements, 'sendSignal()' acquires
// the lock and calls 'cv.notify_all()', thus the signal was 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();
}
};
我遇到的问题是,在解锁“访问”期间,由于交错而偶尔会丢失信号。互斥和呼叫&#39; wait()&#39;在condition_variable上。我该如何防止这种情况?
答案 0 :(得分:2)
您应该只有一个互斥锁。我不明白为什么你需要访问。使用mtx保护等待变量和条件变量。
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; } } };
等待变量和条件变量状态绑定在一起,因此它们应被视为一个关键部分。