条件变量应该具有相对于notify()
和unlock_sleep()
的单个顺序(在wait()
内使用的虚函数调用,其中互斥锁被解锁并且线程作为一个原子序列休眠(运营)运营。要使用任意可锁定std::condition_variable_any
实现此功能,通常会在内部使用另一个互斥锁(以确保原子性和睡眠状态)
如果内部unlock_sleep()
和notify()
(notify_one()
或notify_all()
)操作相对于彼此不是原子操作,则可能会有线程解锁互斥锁,另一个线程信令然后原始线程进入睡眠状态,从不醒来。
我正在阅读std :: condition_variable_any的libstdc ++和libc ++实现并注意到this code in the libc++ implementation
{lock_guard<mutex> __lx(*__mut_);}
__cv_.notify_one();
内部互斥锁被锁定,然后在信号操作之前立即解锁。这不是我上面描述的问题吗?
答案 0 :(得分:1)
C ++ 11及更高版本的标准明确地说&#34; notify_one
和notify_all
的执行应该是原子的&#34;。所以在某种意义上,我认为你是正确的,内部互斥锁应该通过调用保持平台的基础条件变量notify call(例如pthread_cond_signal()
)
但是,我不认为libc ++实现会导致错过通知,因为没有通知线程在锁上同步,等待线程传递给wait()
(或两个线程之间的某些其他同步) )在调用notify_one()
(或notify_all()
)时,无法确保两个线程中的哪一个首先是“{1}}。无论如何要通知或等待。因此,如果在libc ++的当前实现中可能错过通知,那么如果更改libc ++以将其内部锁定保持在其平台的通知API中,则也可能错过该通知。
所以我认为libc ++可以调用&#34;好像&#34;规则说notify_one()
/ notify_any()
的实施是足够原子的&#34;。