多线程信号cond_wait()为什么使用while

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 )是否满足后,代码才继续往下运行。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值