考虑以下示例类,该类允许一个线程等待来自另一个线程的信号。
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();
}
};
我遇到的问题是,在解锁“互斥”互斥锁和在condition_variable上调用“ wait()”之间的时间间隔内,由于交织有时会丢失信号。我该如何预防?
最佳答案
您可能应该只有一个互斥锁。我不明白您为什么需要访问权限。使用mtx保护等待变量和条件变量。
类同步
{
std :: mutex mtx;
std :: condition_variable cv;
布尔等待;
上市:
同步()
:等待中(false)
{
}
同步(const Sync&);
〜Sync()
{
sendSignal();
}
void waitForSignal()
{
std :: unique_lock lck(mtx);
如果(正在等待)
{
等待=真;
cv.wait(lck);
}
}
无效sendSignal()
{
std :: unique_lock lck(mtx);
如果(等待)
{
cv.notify_all();
等待=假;
}
}
};
等待变量和条件变量状态联系在一起,因此应将它们视为单个关键部分。