首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何修复条件变量等待/通知的争用条件

如何修复条件变量等待/通知的争用条件
EN

Stack Overflow用户
提问于 2017-07-27 20:54:07
回答 1查看 1.5K关注 0票数 2

这个问题的答案是错误的,因为它有可能陷入僵局。Condition Variable - Wait/Notify Race Condition

我找不到解决种族问题或死锁问题的办法。

想象一下我们有两条线。现在的目标如下。

代码语言:javascript
复制
first condition:
Thread 1 Waits
Thread 2 Notifies

second condition:
Thread 2 Notifies
Thread 1 Should not wait and continue normal execution.

如何在没有通知队列的情况下正确地实现这一点?因为我希望这部分代码尽可能快地运行,并使用一个布尔值,而不是将项添加到队列中。另外,只有两个线程,所以对我来说,队列的使用似乎过分了。

当存在竞争条件时,伪代码:

代码语言:javascript
复制
Thread 1:
lock(x);
if(!signaled)
{
    unlock(x); // ********
    // still small gap, how to avoid?
    cv.wait(); // forget spurious wakeup for sake of simplicity 
    signaled = false;
}
else // ********
    unlock(x);

Thread 2:
lock(x);
signaled = true;
cv.notify();
unlock(x);

现在,如果删除两行注释有********的争用条件,则将解决死锁的问题,并引入死锁的可能性,其中Thread1在拥有锁时等待,而Thread2则被锁定x。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-07-27 21:00:39

你困惑的根源是你对条件变量的误解。它们的固有特征是锁释放和进入等待模式是原子完成的,也就是说,在两者之间没有发生任何事情。

因此,在变量进入等待模式之前,不可能对变量进行任何修改,因为锁不会被释放。这是任何符合标准的conditional_variable实现的基本保证,例如,下面是std::conditional_variable参考页面的摘录

variable/wait

原子地释放锁,阻塞当前正在执行的线程,并将其添加到等待执行的线程列表中。当执行notify_all()或notify_one()时,线程将被解除阻塞。它也可能是伪造的。解除阻塞时,不管原因如何,重新获取锁并等待退出。如果此函数通过异常退出,则还将重新获取锁。(直到C++14)

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45360825

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档