为什么条件变量的wait函数需要传入一锁作为参数

当等待的条件不满足时,pthread_cond_wait()内部将执行两个步骤,并保证两个操作的原子性:
1.将当前线程加入条件信号的等待队列。
2.解作为参数传入的锁,解除对临界资源的锁定。

用反证法证明,若去掉锁参数,pthread_cond_wait()将只执行步骤1,则可能的代码如下:

lock();
while(条件不满足)
{
    
    
	unlock();//#1:解除对临界资源的锁定。
	pthread_cond_wait(condA);//#2:当前线程加入等待队列,阻塞
	lock();//#3:再次判断之前,对临界资源保护
}
doSomething();
unlock();

要注意到,#1和#2两步已经不是原子操作了,那么就有可能有如此情景:在当前线程(A)执行完#1行代码后到执行#2代码前的时间间隔里,另一线程(B),获取到了锁,修改了条件使其满足,然后发送了信号condA。而此时线程A还未被加入到condA的等待队列中,造成线程A错过了通知一直阻塞,直至下一次通知,如果没有下一次通知,那么A将永远等待下去,比如B也需要A的相关条件变量通知才能再次发出condA的通知。此时逻辑已经出了问题,而如果保证#1和#2的原子性可以避免出现上述问题。

此为,为保证“解锁”和“加入等待队列”两操作的原子性,条件变量的wait函数需要传入一锁作为参数。

猜你喜欢

转载自blog.csdn.net/TABE_/article/details/126374251