C++确认通知

Notify with confirmation in C++

本文关键字:通知 确认 C++      更新时间:2023-10-16

我有一些并行运行的循环,有这些行:

std::unique_lock <std::mutex> lock(_condLoopMutex);
_condLoopCondition.wait(lock, [this]() { return _conditionReady || _condLoopStopped; });
_conditionReady = false;
// DO SOMETHING

布尔变量

_conditionReady

通过以下构造设置在并行螺纹中:

_conditionReady = true;
_condLoopCondition.notify_one();

但是,有时我的程序会冻结。似乎通知来自函数"等待"传递参数和检查"_conditionReady"变量之间。

为了避免这种情况,我实现了以下内容:

while (_conditionReady && !_condLoopStopped)
    {
        _condLoopCondition.notify_one();
        std::this_thread::sleep_for(std::chrono::microseconds(100));
    }

以便它不断通知,直到

_conditionReady == false

这意味着等待结束了。

这是此问题的唯一解决方案 - 重新通知直到等待结束?是否有其他常规方法可以处理这些问题?

首先,睡眠从来都不是解决错误的方法。它应该在每次使用时生成编译器警告,这将传达相同的消息。

现在,每当您修改受条件保护的控制变量时,都应该在持有互斥锁时完成 - 通常与cond.wait()中使用的相同。您的代码不会执行此操作。

您只需

在修改_conditionReady变量时持有互斥锁。这样可以确保在检查变量值和开始等待之间不会修改变量,从而避免争用条件。确保在调用notify_one之前或之后释放互斥锁,以允许等待线程唤醒(如果在调用通知后执行此操作,则可以通过唤醒等待线程来引入较小的性能损失,然后当互斥锁被锁定时,它会立即返回睡眠状态,然后在互斥锁解锁时再次唤醒)。例如:

{
  std::unique_lock <std::mutex> lock(_condLoopMutex);
  _conditionReady = true;
}
_condLoopCondition.notify_one();