为什么条件变量有时会被错误地唤醒?

时间:2010-04-28 06:24:19

标签: concurrency condition-variable

我已经知道你使用条件变量的方式是

lock
while not task_done
  wait on condition variable
unlock

因为有时条件变量会自发唤醒。但我永远不明白为什么会这样。在过去,我认为制作一个没有这种行为的条件变量是很昂贵的,但仅此而已。

那么......为什么你需要担心在等待条件变量时错误地被唤醒?

2 个答案:

答案 0 :(得分:3)

不是条件变量会错误地唤醒;条件变量只有在从另一个线程发出信号后才会被唤醒。但是,有可能在线程被重新调度执行时,其他一些线程已经设法找到您正在等待的资源,因此需要仔细检查。例如,如果一组线程x,y,z正在等待先前保存的某个资源R,并且x,y,z,w通过条件变量进行通信...假设w完成了R并且信号x ,Y,Z。因此,x,y和z都将从等待队列中取出并放置在运行队列中以便执行。假设首先调度x ...然后它获取R,然后它可能被置于休眠状态,然后y可能被调度,因此当y运行时,y先前等待的资源R仍然不可用所以你有必要再次入睡。然后z醒来,z也发现R仍然在使用,所以z需要再次回去睡觉等等。

如果您只有两个线程,并且条件变量仅在其中两个之间共享,则有时可以执行该检查。但是,如果你想让你的应用程序变得动态并且能够扩展到任意数量的线程,那么做这个额外的检查是很好的习惯(更不用说更简单和更少担心),因为它需要大多数情况。

答案 1 :(得分:1)

线程可以在没有发出信号的情况下醒来。这称为虚假唤醒。然而,恰恰为什么它们的出现是一个似乎陷入迷信和不确定性的问题。我看到的原因包括线程实现工作方式的副作用,或者被故意添加以强制程序员正确使用循环而不是wait周围的条件。