1

问题是关于我浏览的关于条件变量的帖子。条件变量

作者先举一个bug的例子:

/* in thread 1 */
pthread_mutex_lock(mx); 
if (state == GOOD) {
    pthread_mutex_unlock(mx);  // Here !
    wait_for_event();
    pthread_mutex_lock(mx);
}
pthread_mutex_unlock(mx);


/* in thread 2 */
pthread_mutex_lock(mx);
state = GOOD;
pthread_mutex_unlock(mx);
signal_event(); /* expecting to wake thread 1 up */

并解释如下:

'这个伪代码示例带有一个错误。如果调度程序决定在 pthread_mutex_unlock(mx) 之后但在 wait_for_event() 之前将上下文从线程 1 切换到线程 2,会发生什么情况。在这种情况下,线程 2 不会唤醒线程 1,而线程 1 将继续休眠,可能永远。

我知道应该如何使用条件变量,正如作者稍后在同一篇文章中所展示的那样。

我可以看到,在这个错误的示例中,'state == GOOD' 判断和 'wait_for_event()' 没有被互斥锁作为一个整体锁定。如果线程 1 在第一个 ' pthread_mutex_unlock(mx); ',线程 2 可以将 'state' 更改为其他东西(坏?),并发出信号唤醒线程 1 以继续 'state == GOOD' 逻辑,我认为这是错误的。

但是为什么作者说'在这种情况下,线程 2 不会唤醒线程 1,线程 1 将继续休眠,可能永远。'?

不是'signal_event();' 仍然在线程 2 中调用?我的理解完全正确吗?

4

1 回答 1

0

该错误是由 和 的语义引起signal_event()wait_for_event()。如果signal_event()在没有人卡的情况下调用wait_for_event(),则信号丢失。

除了上下文切换,如果线程 2 运行快而线程 1 运行慢,也会出现同样的问题。在这种情况下,线程 1 中的时间

pthread_mutex_unlock(mx);

wait_for_event();

可能是当 thread2 完成所有操作时,将信号发送到遗忘状态(因为没有人在等待它)。然后线程 1 等待,它永远不会得到信号(除非线程 2 出于某种原因再次运行)。

于 2012-10-10T09:26:04.430 回答