cond_broadcast工作原理:唤醒线程抢mutex失败后会如何处理?
问题背景
以下是相关示例代码:
int students[2] = {0}; cond_t conds[2]; mutex_t global; void onArrival(int faculty) { mutex_lock(&global); int other = faculty ? 0:1; while(students[other]>0) cond_wait(&conds[faculty],&global); students[faculty]++; mutex_unlock(&global); } void onLeave(int faculty) { mutex_lock(&global); students[faculty]--; int other = faculty ? 0:1; cond_broadcast(&conds[other]); mutex_unlock(&global); }

疑问解答
针对cond_broadcast唤醒线程后mutex尚未释放的场景,实际运行行为如下:
- 不存在唤醒丢失:所有被
cond_broadcast唤醒的线程,会进入关联的global互斥锁的等待队列,不会因为当前锁未释放就永久休眠。当第17行mutex_unlock执行后,操作系统会按调度策略从锁等待队列中依次给线程分配互斥锁,线程拿到锁后才会从cond_wait调用中返回,继续执行后续逻辑。 - 不会出现持续忙等待:现代操作系统的互斥锁普遍采用futex(快速用户态互斥锁)实现,线程抢锁失败后只会在用户态短暂自旋几次,若仍未拿到锁就会进入内核态休眠,不会持续占用CPU。就算同时唤醒1000个线程,也不会出现大量线程空转消耗资源的情况。
- 额外说明:代码中
cond_wait外层用while而非if判断条件是标准正确写法,因为线程拿到锁返回后,可能有更早拿到锁的线程已经修改了共享变量的值,导致等待的条件不再成立,此时需要重新校验条件,不满足的话要再次调用cond_wait进入等待。
内容的提问来源于stack exchange,提问作者algo
相关产品推荐
相关产品推荐

