考虑以下条件变量的简单示例:
bool pause = true;
boost::mutex::scoped_lock lock(m_mutex);
while (!pause) cv.wait(lock);
和
boost::mutex::scoped_lock lock(m_mutex);
pause = false;
cv.notify_one();
如果我们在支持字节粒度更新的处理器上运行代码,我们是否本质上需要 scoped_lock
或任何其他锁。这实质上意味着 bool 的分配是原子的,这通常是 x86 处理器的情况。
当两个线程在两个不同的处理器上运行并具有单独的缓存时,它是否与变量同步有关?
最佳答案
是的,使用 atomic 是不够的。
boost 效率的 CV 可能会被虚假地唤醒,而那些虚假的查找(或类似问题)可能会导致写入丢失。
想象一下虚假的唤醒。接收线程检查 bool,什么也看不到 (false),然后被抢占。有人通知所有人并设置 bool 值。通知被丢弃,因为接收线程已经在处理一个。接收线程现在完成,但错过了消息。
现在,在设置 bool 之后和 cv 通知之前的某个时间序列重叠的发件人中添加一个锁。此通信孔不再存在。
(即使没有虚假唤醒,多个通知有时也会导致类似的问题。)
您不必在通知时持有锁(实际上这是一种悲观主义),但通常情况下,锁必须在写入后和通知前持有一段时间。
关于c++ - 使用带条件变量的锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39632294/