没有保持锁的条件变量上的信号

问题描述 投票:6回答:2

因此,我刚刚发现,如果您不持有c ++ 11的锁,则发信号通知条件变量是合法的。这似乎打开了一些令人讨厌的比赛条件的大门:

std::mutex m_mutex;
std::condition_variable m_cv;

T1: 
  std::unique_lock<std::mutex> lock(m_mutex);
  m_cv.wait(lock, []{ return !is_empty(); });

T2:
  generate_data();
  m_cv.notify();

是否可以保证T1永远不会在以下情况下出现:首先检查is_empty()(返回true),然后被T2抢占,T2创建一些数据并在实际等待之前发信号通知条件变量?] >

如果保证可以正常工作(我想是这样,否则它似乎是故意的错误API设计),对于linux和stdlibc++,这实际上是如何实现的?似乎我们需要另一个锁来避免这种情况。

因此,我刚刚发现,如果您不持有c ++ 11的锁,则发信号通知条件变量是合法的。似乎打开了一些讨厌的竞赛条件的门:std :: mutex m_mutex; std :: ...

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

检查谓词和等待不是在std::condition_variable::wait中自动执行的(解锁锁和休眠是自动执行的)。如果在该线程持有互斥锁的同时另一个线程可以更改谓词的值,则有可能在谓词检查和睡眠之间发生通知,并实际上丢失了通知。


3
投票
不能保证-如果您不想错过信号,则必须在通知之前锁定互斥锁。某些应用程序可能与信号丢失无关。
© www.soinside.com 2019 - 2024. All rights reserved.