深入理解条件变量(虚假唤醒)
深入条件变量
pthread_cond_wait()
和pthread_cond_signal()
的伪实现
1 |
|
考虑2个线程, A 和 B
线程A执行pthread_cond_wait()
后,线程B执行pthread_cond_signal()
,此时2个线程同时竞争互斥量cond->mutex
(语句2)
线程A在执行完语句1后就尝试进入等待队列,(此时mutex
被释放,程序以为线程A已经被挂起,但实际上只是在尝试进入等待队列),
- 线程B获得锁
cond->mutex
,修改条件cond->value
后,发现等待队列为空if (cond->waiter)
不成立,则释放锁,线程A获得锁,发现条件被改变后又释放锁(因为没有加入到等待队列,又释放了锁,所以看起来像被唤醒了一样,(实际上根本没加入到等待队列中)
所以被
pthread_cond_wait()
唤醒不一定要加入到等待队列中,具体看pthread_cond_signal()
执行的时机
- 线程A获得锁
cond->mutex
,然后将自己加入到等待队列中,释放锁后挂起,然后线程B获得锁,if (cond->waiter)
成立,将线程A从等待队列中移出(即唤醒)
3个线程 A B C
在上面情况的基础上,若线程C在线程A\B执行前已经在等待队列上,再次重复上面的情况,
- 线程A先获得锁,那么还是先加入到等待队列中,然后线程B在唤醒一个,线程C仍在等待队列中
- 线程B先获得锁,修改条件,并且把线程C唤醒了,释放锁后,线程A把自己”唤醒了”,
所以说pthread_cond_signal()
至少能唤醒一个等待该条件的线程
线程虚假唤醒
在线程B唤醒线程C释放锁mutex
后,线程A(pthread_cond_wait
)返回,**但是线程C可能修改条件(其他情况也可能导致条件被修改)**,故造成线程被虚假唤醒,
解决方法
1 |
|
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!