避免在pthread_cond_wait和pthread_cond_signal时死锁
avoiding deadlock when pthread_cond_wait and pthread_cond_signal
我有一个关于使用pthread条件变量的问题。一般用例是这样的
//thread 1:
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond, &mutex);
do_something()
pthread_mutex_unlock(&mutex);
//thread 2:
pthread_cond_signal(&cond);
现在我知道pthead_cond_wait将解锁互斥锁并进入睡眠状态,当唤醒时,它将锁定互斥锁,然后从调用返回,但如何确保线程2的信号在线程1处于等待状态后到达线程1。可能出现thread2先运行,然后thread1导致丢失唤醒的情况。
如果我再次在线程2中使用互斥锁,那么也可能发生thread2将获得锁,它将发出信号,而thread1仍在尝试获取锁。这将再次导致丢失唤醒。
如何确保来自条件变量的信号到达等待它的线程?
谢谢
你的"通用用例"是不正确的。条件变量必须与某个共享状态的条件配对,称为谓词。一般用例是:
线程1:pthread_mutex_lock(&mutex);
while (!condition)
pthread_cond_wait(&cond, &mutex);
do_something(); /* Requiring 'condition' to be true */
pthread_mutex_unlock(&mutex);
线程2:pthread_mutex_lock(&mutex);
do_something_else(); /* That sets 'condition' true */
pthread_cond_broadcast(&cond);
pthread_mutex_unlock(&mutex);
…其中condition
在某些由mutex
保护的共享状态上,例如,condition
可能正在检查共享队列是否为非空。
在这个结构中不会有丢失的唤醒,因为等待线程总是在等待前检查条件。如果条件已经为真,它不会等待——因为它持有保护条件的互斥锁,所以在检查和等待之间也不能变为真。
(注意pthread_cond_broadcast()
通常是正确的函数,pthread_cond_signal()
是在许多情况下适用的优化)。
这完全取决于你的设计。您可以使用bool变量(例如issignals)来同步两者。以下内容(请参考)
//thread 1:
pthread_mutex_lock(&mutex);
if(isSignalled == 0){
pthread_cond_wait(&cond, &mutex);
}
isSignalled = 0;
do_something()
pthread_mutex_unlock(&mutex);
//thread 2:
pthread_mutex_lock(&mutex);
isSignalled = 1;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
相关文章:
- 在 c++11 中为 pthread 设置调度参数
- 如果不包含 pthread,为什么 GCC 的线程标准库实现会抛出异常?
- pthread只有在线程数量较少时才可以正常工作
- pthread执行时间比顺序执行时间差
- 使用 -pthread 如何不违反 ODR 规则?
- 使用 pthread 的多线程
- 销毁 pthread 互斥体和 C++ 中的取消初始化顺序
- 函数 AfxEndThread 中的读取访问冲突"pThread-> was nullptr"
- 锁定步进pthread互斥
- Pthread段错误,使用指向main中变量的指针
- pthread导致的内存泄漏
- GCC:--静态链接到pthread的整个存档配方在最近的GCC版本中停止工作
- 正确地编写一个类,并将pthread与vlc库和c++一起使用
- 直接读取 pthread 互斥锁的所有者字段是否安全?
- 为什么 pthread 会减慢代码速度?
- 对 pthread CLion 的未定义引用
- C++ 17:pthread的生成文件标志
- 将带有结构的参数传递给 pthread
- Posix 线程类和启动例程 (pthread)
- 在 pthread 中使用共享变量