我让线程 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() 版本,它需要一个谓词,但结果基本相同。也就是说,谓词的主体执行检查,但在返回之前,条件的值会更改并发送通知。然后谓词返回。
我该如何解决这个问题?
您应该通过让线程 2 在更改标志之前锁定条件的互斥体来修复此竞争条件。
您正在描述未受保护的标志和条件发生的典型竞争条件。这些竞争条件是条件使用中互斥锁模式的原因。简而言之,始终有一个互斥锁来保护检查条件值所涉及的变量。
在线程 2 的代码中:
unique_lock<mutex> ul(m);
condition = false;
cv.notify_one();
由于对 condition
的读/写访问冲突,您遇到了
数据竞争。这意味着您的程序的行为未定义。
cv
上的竞争条件是您最不用担心的:程序可以做任何事情!
的谓词形式来检查全局变量。这涵盖了两种可能的竞争条件。如果 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();
}