使用带条件变量的锁

Using a lock with condition variables

考虑以下条件变量的简单示例:

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 是不够的。

提高效率的 CV 可能会被虚假唤醒,而那些虚假查找(或类似问题)可能会导致写入丢失。

想象一下虚假的唤醒。接收线程检查 bool,什么也看不到 (false),然后被抢占。有人通知所有人并设置布尔值。通知被丢弃,因为接收线程已经在处理一个。接收线程现已完成,但错过了消息。

现在,在设置 bool 之后和 cv 通知之前的某个时间序列重叠的发件人中添加一个锁。这个通讯孔已经不存在了

(即使没有虚假唤醒,多次通知有时也会导致类似的问题。)

通知的时候不一定要持有锁(其实这是一种悲观的说法),但是一般情况下,一定要持有锁post-write and pre-notify一段时间。