为什么条件变量需要锁定(因此也需要互斥锁)

lau*_*svr 13 c++ concurrency flags multithreading c++11

条件变量是c ++ 11的一个方面我还在苦苦挣扎.从我收集到的条件变量非常类似于信号量.

但话说回来,信号量不需要锁定才能运行.条件变量可以.而锁又需要一个互斥锁.因此,为了使用信号量的相当简单的功能,我们现在不仅需要管理条件变量.但也是一个互斥锁和一个锁.

那么为什么条件变量需要这个呢?通过添加此要求可以提供哪些附加功能?

Mik*_*our 5

条件变量通常用于表示状态的变化.通常需要互斥锁来进行更改,以及以下信号,即原子.

信号量封装一些状态(标志或计数器)以及信令机制.条件变量更原始,仅提供信号.

  • 至少在C++中,没有必要用锁来保护信令.实际上,根据实现如何处理等待线程的调度,在锁内执行信令可能对性能有害.虽然在某些情况下程序逻辑可能依赖于状态变化和信号以原子方式发生的事实,但在使用条件变量时通常不是这样. (2认同)

Mik*_*ine 5

通常,一旦您已经通过状态变量发出信号更改,就需要运行一些代码来处理该更改,并且该代码必须安全地读取更改的数据。如果您没有与cv关联的锁,那么正在等待cv的线程可能会醒来,然后尝试(失败)获取与数据关联的锁,因此必须再次屈服。使用CV / Lock组合,只有在线程可以将相关锁作为一个单元获得并因此更有效的情况下,底层系统才能唤醒您的线程。

它本身不太可能提供简历,因为它没有提供高于信号本身的任何数据。如果您想像使用cv-例如带有生产者和使用者的线程安全链表,则可以使用表示的变量{list, cv, lock}。在这种情况下,您将锁定,更改列表,释放锁定,然后向简历发送信号。在您的使用者线程上,您很可能需要在收到信号通知后就采取行动,以便在列表上行动,因此一旦从发出信号的CV中醒来就获得了该锁是一件好事

看一下类似Windows(:: CreateEvent)上的事件的事件,这些事件是没有隐式锁的cv,在很多情况下,它们都具有与之关联的锁,但实际上并没有内置在锁中。

尽管这不是在pthreads中创建条件变量的最初原因(它们使用锁来保护cv本身,而c ++不再需要此条件),但使用cv的锁的原因和实用性已迁移到此答案中的内容。