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

发布于 2024-08-30 12:42:13 字数 217 浏览 5 评论 0原文

我很久以来就知道使用条件变量的方式是

lock
while not task_done
  wait on condition variable
unlock

因为有时条件变量会自发唤醒。但我一直不明白为什么会这样。过去我读过,创建一个没有这种行为的条件变量是昂贵的,但仅此而已。

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

I've known for eons that the way you use a condition variable is

lock
while not task_done
  wait on condition variable
unlock

Because sometimes condition variables will spontaneously wake. But I've never understood why that's the case. In the past I've read it's expensive to make a condition variable that doesn't have that behavior, but nothing more than that.

So... why do you need to worry about falsely being woken up when waiting on a condition variable?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

中性美 2024-09-06 12:42:13

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

如果你正好有两个线程,并且条件变量仅在它们两个之间共享,则有有时在某些情况下可以不执行该检查。但是,如果您想让您的应用程序动态化并且能够扩展到任意数量的线程,那么最好养成习惯(更不用说更简单且更不用担心)进行额外的检查,因为它是大多数情况。

It isn't that the condition variable will erroneously wake up; the condition variable will only wake up if it has been signalled from another thread. However, it is possible that by the time the thread has been re-scheduled for execution, some other thread has already managed to nab the resource on which you were waiting, and so it is necessary to double-check. For example, if a group of threads x,y,z are waiting on some resource R that w was previously holding, and x,y,z,w communicate through a condition variable... suppose w is done with R and signals x,y,z. So, x,y, and z will all be taken off of the wait queue and placed in the runqueue to be scheduled for execution. Suppose x is scheduled first... so then it acquires R, and then it might be put to sleep, and then y might be scheduled, and so when y is running, the resource R on which y was previously waiting is still not available, so it is necessary for y to go to sleep again. Then z wakes up, and z also finds that R is still in use, so z needs to go back to sleep again, etc.

If you have exactly two threads, and the condition variable is shared between just the two of them, there are sometimes situations where it is ok to not perform that check. However, if you want to make your application dynamic and capable of scaling up to an arbitrary number of threads, then it's good to be in the habit (not to mention much simpler and less worrisome) to do that extra check as it is required in most situations.

窝囊感情。 2024-09-06 12:42:13

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

Threads can wake up without being signaled. This is called a spurious wakeup. However, just precisely why they occur is a question that seems to be mired in superstition and uncertainty. Reasons I have seen include being a side effect of the way threading implementations work, or being intentionally added to force programmers to properly use loops instead of conditionals around wait.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文