使用带条件变量的锁
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一段时间。
考虑以下条件变量的简单示例:
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一段时间。