You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何此Condvar的wait与notify用法不会产生死锁?

关于Condvar示例中竞态情况的解释

你提的这个问题完全合理,乍一看好像确实会出现死锁,但其实Condvar的wait方法藏着关键机制,完美解决了这个问题,咱们来仔细拆解:

首先,先明确你担心的场景:主线程先执行到标记#2处,成功获取Mutex的锁,这时候子线程才开始运行,在#1处尝试获取锁会被阻塞,看起来主线程会一直卡在while !*started的循环里,子线程又拿不到锁修改值,陷入死循环。

但实际上,当主线程调用cvar.wait(started).unwrap()的时候,发生了两个原子性的操作:

  1. 自动释放当前持有的Mutex锁
  2. 让当前线程进入等待状态,直到收到Condvar的通知

这就意味着,主线程一旦进入wait,锁就被释放了,子线程立刻就能拿到#1处的锁,修改*started为true,然后调用cvar.notify_one()发送通知。

当主线程收到通知后,会重新获取Mutex锁,然后回到while循环的判断条件,这时候*started已经是true了,循环就会正常退出。

另外还要补充一点:官方示例用while而不是if判断条件,是因为Condvar存在虚假唤醒的可能——线程可能在没有收到notify的情况下被唤醒。用while循环可以确保每次唤醒后都重新检查条件,避免因为虚假唤醒导致程序逻辑出错。

咱们再把两种可能的执行流程理清楚:

  • 场景A:子线程先运行,拿到#1的锁,修改started为true并通知Condvar,之后主线程拿到#2的锁,检查*started直接为true,跳过循环。
  • 场景B:主线程先拿到#2的锁,发现*started为false,调用wait释放锁,子线程拿到#1的锁修改值并通知,主线程被唤醒重新拿锁,检查条件满足退出循环。

两种场景下程序都能正常运行,完全不会出现你担心的死锁问题~

内容的提问来源于stack exchange,提问作者Wynell

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 10:39:06