写多线程同步,条件变量 std::condition_variable 是常用组件。几乎所有教程都会强调:等待条件的时候,一定要用while,不能用if。很多人记结论,却不懂为什么会有虚假唤醒。

虚假唤醒含义:没有别的线程调用notify,wait函数自己就返回了。这不是C++标准bug,是操作系统底层允许的行为,POSIX、Windows原生条件变量都存在这个特性。

操作系统内核实现条件变量的时候,出于简化内核逻辑,允许自发唤醒等待线程。

如果使用if判断:

线程被虚假唤醒,if条件直接放行,此时业务条件并不满足,程序逻辑出错。

while循环的逻辑:唤醒之后,再次校验业务条件;条件不满足,继续wait休眠,完美抵御虚假唤醒。

下面有两个高频坑我们经常遇到:

1. wait之前必须加锁,传入unique_lock;

2. notify的顺序不能乱,先改共享变量,再notify;顺序写反,会出现线程永久卡死。

条件变量适合生产者消费者模型,是并发基础组件。这个知识点面试出现频率极高,面试官很喜欢追问while和if的区别。

刚学条件变量的时候,你是不是也疑惑为什么不能用if?

 

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐