C++11 我可以确保condition_variable.wait()不会错过通知吗?

问题描述 投票:0回答:3

我让线程 1 执行以下代码:

unique_lock<mutex> ul(m);
while(condition == true)
    cv.wait(ul);

线程 2 执行此代码:

condition = false;
cv.notify_one();

不幸的是我遇到了时间问题:

T1: condition checks true
                            T2: condition set to false
                            T2: cv.notify_one()
T1: cv.wait()

线程 1 完全错过了通知并在 wait() 上保持阻塞状态。我尝试使用 wait() 版本,它需要一个谓词,但结果基本相同。也就是说,谓词的主体执行检查,但在返回之前,条件的值会更改并发送通知。然后谓词返回。

我该如何解决这个问题?

c++ multithreading c++11 condition-variable
3个回答
8
投票

您应该通过让线程 2 在更改标志之前锁定条件的互斥体来修复此竞争条件。

您正在描述未受保护的标志和条件发生的典型竞争条件。这些竞争条件是条件使用中互斥锁模式的原因。简而言之,始终有一个互斥锁来保护检查条件值所涉及的变量。

在线程 2 的代码中:

unique_lock<mutex> ul(m);
condition = false;
cv.notify_one();

0
投票

由于对 condition 的读/写访问冲突,您遇到了

 数据竞争。这意味着
您的程序的行为未定义

cv

 上的竞争条件是您最不用担心的:程序可以做任何事情!


0
投票
您应该使用 std::wait

的谓词形式来检查全局变量。这涵盖了两种可能的竞争条件。如果 thread1 首先到达 wait(),那么它就会按照您的预期被通知解除阻塞。如果线程 2 首先到达

notify_all()
,则线程 1 将被
stopCondition
全局布尔值解除阻塞。
全球

mutex m; atomic_bool stopCondition{false};

线程 1

unique_lock<mutex> ul(m); cv.wait(ul, [&stopCondition](){return stopCondition;})

线程2

{ unique_lock<mutex> ul(m); stopCondition = true; cv.notify_one(); }

© www.soinside.com 2019 - 2024. All rights reserved.