信号在条件变量上而无需锁定锁
signal on condition variable without holding lock
,所以我发现如果您不在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抢占,从而创建一些数据并在我们可以实际等待之前就标志着条件变量?
如果保证这可以正常工作(我想是这样,否则似乎是故意的API设计),那么这是如何实现Linux和stdlibc++
的实际实现?似乎我们需要另一个锁来避免这种情况。
检查谓词和等待在std::condition_variable::wait
中未进行原子(解锁锁定和睡眠是原子上执行的)。如果另一个线程在此线程保持静音时可以更改谓词的值,则可能在谓词检查和入睡之间发生通知,并有效地丢失。
在您的示例中,如果T2
中的generate_data()
可以在不持有m_mutex
的情况下更改is_empty()
的结果,则可能在T1
检查is_empty()
和在m_cv
上睡觉之间发生通知。在更改对谓词和通知之间的任何时间都保持静音,足以保证在另一个线程中谓词检查和wait
调用的原子。看起来像:
{
std::lock_guard<std::mutex> lk(m_mutex);
generate_data();
}
m_cv.notify();
甚至
generate_data();
std::lock_guard<std::mutex>(m_mutex); // Lock the mutex and drop it immediately
m_cv.notify();
不能保证 - 如果您不想错过信号,则必须在通知之前锁定静音。一些应用程序可能对缺少信号不可知。
来自MAN PTHREAD_SIGNAL:
pthread_cond_signal()或pthread_cond_broadcast()函数可以由线程调用,无论它是否当前拥有调用pthread_cond_wait()或pthread_cond_timedwait()在等待期间与条件变量相关联的螺纹螺纹的互联面;但是,如果需要可预测的调度行为,则utex将被呼叫pthread_cond_signal()或pthread_cond_broadcast()的线程锁定。
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- 在没有太多条件句的情况下,我如何避免被零除
- 基于多个条件处理地图中的所有元素
- 如何找到锁定Linux futex的C++行
- 条件constexpr函数
- G锁定铸造到基础上会释放模拟行为
- 无论条件是否为true,if总是在c++中执行
- 我可以使用条件运算符初始化C风格的字符串文字吗
- 基于模板值的条件变量
- 多个If语句与使用逻辑运算符计算条件的单个语句的比较
- 如何检查线程是否锁定
- 如何在C++中找到active directory中禁用和锁定的窗口帐户
- 我应该在锁定TBitmap画布后解锁它吗
- 如何杀死被条件变量锁定的线程?
- 通过检查条件并重新检查来获取锁定
- 使用文件锁定的进程之间的条件变量
- 信号在条件变量上而无需锁定锁
- 为什么条件变量需要锁定(因此也需要静音)
- 带条件变量的升压锁定机制
- 具有if条件的作用域锁定