多线程中Condition Signal工作机制及示例场景疑问
结论
你推导的永久休眠场景不存在,推导逻辑存在错误,核心是对互斥锁唤醒流程、条件变量等待队列的行为理解有误。
cond_t c; mutex_t m; int queue_size = 0; void enqueue(item x) { mutex_lock(&m); /* add x to tail */ queue_size++; cond_signal(&c); // Line 1 mutex_unlock(&m); } item dequeue() { mutex_lock(&m); if (queue_size == 0) cond_wait(&c, &m); // Line 2 /* remove from head */ queue_size--; mutex_unlock(&m); }
错误点解释
- 核心误解:你认为t2被
cond_signal唤醒后如果拿不到锁,会回到条件变量的等待队列再次休眠,这个认知是错误的。
条件变量的等待队列和互斥锁的等待队列是完全独立的两个队列:- t2调用
cond_wait时,会原子释放锁m、加入条件变量c的等待队列进入休眠,此时它不在m的等待队列中 - t1调用
cond_signal后,会把t2从条件变量c的等待队列中移除,转移到互斥锁m的等待队列中,此时t2的休眠是阻塞在互斥锁m上,和条件变量c已经没有关系了
- t2调用
- 当t1后续执行
mutex_unlock(&m)时,会唤醒m的等待队列中的t2,t2成功拿到锁后就会从cond_wait调用返回,继续执行后续逻辑,不会出现信号丢失、永久休眠的问题。
额外注意
这段代码本身存在一个常见的条件变量使用错误:dequeue中判断queue_size == 0用了if而非while循环,无法处理虚假唤醒的情况,实际生产环境中需要改成while循环判断条件是否满足。
内容的提问来源于stack exchange,提问作者rolen
相关产品推荐
相关产品推荐

