libc ++实现std :: condition_variable_any

时间:2017-10-29 18:14:32

标签: c++ multithreading c++11 thread-safety condition-variable

条件变量应该具有相对于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();

内部互斥锁被锁定,然后在信号操作之前立即解锁。这不是我上面描述的问题吗?

libstdc++ seems to have gotten this right

1 个答案:

答案 0 :(得分:1)

C ++ 11及更高版本的标准明确地说&#34; notify_onenotify_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;。