结论:mutex是用来保证A的23句是原子性的,如果原子性被破坏就可能会失去丢失唤醒的信号
这两个线程的所有运行情况,A先和B先
- A先,A阻塞在con_wait里,并释放锁,B拿到锁后修改,并signal,A被唤醒后加锁解锁并继续运行
- B先运行,拿到锁后设为true,发信号,后A运行,拿到锁后直接while不成立继续
如果没有mutex:即下图左边的代码,右边是一种运行可能,这种情况下会con.wait一直阻塞,B的signal丢失
为什么要用while
一个是为了防止spurious wakeup,这种情况比较少见;如果有多个线程等待在一个condition上,当发送一个signal(),系统可能会全部都唤醒,就像broadcast一样(那这是操作系统的问题啊),则若有十个wait(),则9个会经历这种唤醒,所以等待者起床后要再检查一下
另一种情况是发生在多核系统,也是系统的原因,如果要改掉这个bug会让condition操作变得更慢,详细见参考资料[1],所以还是用while吧
参考资料
- https://www.zhihu.com/question/271521213为什么要用while
- cond_wait 为什么需要传递 mutex 参数https://www.zhihu.com/question/24116967
- https://en.m.wikipedia.org/wiki/Spurious_wakeup是spurious wakeup