int empty_slot = 1;
producer()
{
while(1) {
lock(&empty_cnt_lock);
while(empty_slot == 0){
cond_wait(&empty_cond, &empty_cnt_lock);
}
empty_slot --;
unlock(&empty_cnt_lock);
XXXXXXX
}
}
consumer()
{
while(1) {
lock(&empty_cnt_lock);
empty_slot ++;
cond_signal(&empty_cond);
unlock(&empty_cnt_lock);
YYYYYYYY
}
}
使用pthread_cond_signal不会有“惊群现象”产生,他最多只给一个线程发信号。假如有多个线程正在阻塞等待着这个条件变量的话,那么是根据各等待线程优先级的高低确定哪个线程接收到信号开始继续执行。如果各线程优先级相同,则根据等待时间的长短来确定哪个线程获得信号。但无论如何一个pthread_cond_signal调用最多发信一次。
所以网上关于while()是为了避免惊群现象的说法,我认为是错误的。但是为什么要用while(),我认为至少有如下原因:
假如消费者准备唤醒生产者P1(消费者发出信号,释放锁),P1未被唤醒(例如执行正在执行XXXXX代码)。但是,另外一个生产者P2成功获取了互斥锁并且消耗了刚刚产生的空位,empty_slot 变为0。那么当P1真正醒来之后(P2执行完释放锁,消费者在执行YYYYY,P1拿到锁),empty_slot 变成0了,如果不使用while循环,线程会继续往下执行,将empty_slot 错误地修改为负值。
所以,我的观点是,当cond_wait()收到信号后,还要用while()检查一下资源/条件(empty_slot )是否满足后,代码才继续往下运行。