c - 使用条件变量解锁一个线程但互斥锁不会导致死锁?
问题描述
基本问题,但为了简洁起见,我有两个线程在特定条件下bar
解除阻塞foo
,但即使程序运行良好令我惊讶的foo
是,如果首先运行它会导致死锁,这意味着bar
不应该鉴于条件变量永远不会为真,能否继续进行foo
?
pthread_mutex_t lock;
pthread_cond_t cv;
bool dataReady = false;
void foo(void *arg)
{
printf ("Foo...\n");
pthread_mutex_lock(&lock);
while (!dataReady)
{
pthread_cond_wait(&cv, &lock);
}
printf ("Foo unlocked...\n");
dataReady = true;
pthread_mutex_unlock(&lock);
}
void bar(void *arg)
{
printf ("Bar...\n");
pthread_mutex_lock(&lock);
sleep(3);
printf ("Data ready...\n");
dataReady = true;
pthread_cond_broadcast(&cv);
pthread_mutex_unlock(&lock);
}
int main(void)
{
int main()
{
pthread_t t1,t2;
pthread_create(&t1,NULL,foo,NULL);
pthread_create(&t2,NULL,bar,NULL);
pthread_join(t1,NULL);
pthread_join(t2,NULL);
return 0;
}
同样在这种情况下,使用信号量没有意义是吗?
解决方案
pthread_cond_wait(&cv, &lock);
调用时原子地释放互斥锁,唤醒时重新获取它。
这些函数以原子方式释放互斥体并导致调用线程阻塞条件变量 cond;atomically 这里的意思是“原子地相对于另一个线程访问互斥锁,然后是条件变量”。也就是说,如果另一个线程能够在即将阻塞的线程释放后获得互斥锁,那么该线程中对 pthread_cond_broadcast() 或 pthread_cond_signal() 的后续调用将表现得就好像它是在 about-- to-block 线程已阻塞。
成功返回后,互斥锁将被锁定并归调用线程所有。
恕我直言 C++ 文档包含更清晰的解释(我知道语言不同,但操作原理保持不变): https ://en.cppreference.com/w/cpp/thread/condition_variable
- 在用于保护共享变量的同一个互斥锁上获取 std::unique_lockstd::mutex
- 任何一个
- 检查条件,以防它已经更新并通知
- 执行 wait、wait_for 或 wait_until。等待操作以原子方式释放互斥体并暂停线程的执行。
- 当通知条件变量、超时到期或发生虚假唤醒时,线程被唤醒,互斥体被原子地重新获取。如果唤醒是虚假的,线程应该检查条件并继续等待。
推荐阅读
- spring-boot - KafkaConsumer 没有轮询所有消息
- html - safari 没有显示带阴影的圆形 div
- curl - 上传图片时出现错误 {"name":"Bad Request","message":"Unsupported image type","code":0,"status":400}
- css - Bootstrap Carousel 的问题(图像显示但不滑动/更改)
- java - Java中ImageIcon上的内存泄漏
- javascript - 在 AngularJS 数据表之外触发过滤
- java - 如何使用 Selenium Java 从网站中的框架切换
- android-management-api - 设备未同步政策更改
- python - Python 中的 Slack 集成
- regex - 为什么 URL 参数不起作用重写 URL htaccess?