linux多线程之条件变量

         条件变量通过允许线程阻塞和等待另一个线程发送信号的方法弥补了互斥锁的不足,它常和互斥锁一起使用。使用时,条件变量被用来阻塞一个线程,当条件不满足时,线程往往解开相应的互斥锁并等待条件发生变化。一旦其它的某个线程改变了条件变量,它将通知相应的条件变量唤醒一个或多个正被此条件变量阻塞的线程。这些线程将重新锁定互斥锁并重新测试条件是否满足。一般说来,条件变量被用来进行线承间的同步。

         假设有共享的资源sum,与之相关联的mutex 是lock_s.假设每个线程对sum的操作很简单的,与sum的状态无关,比如只是sum++.那么只用mutex足够了.程序员只要确保每个线程操作前,取得lock,然后sum++,再unlock即可.每个线程的代码将像这样

      

add()
    pthread_mutex_lock(lock_s);
    sum++;
    pthread_mutex_unlock(lock_s);
}

  如果操作比较复杂,假设线程t0,t1,t2的操作是sum++,而线程t3则是在sum到达100的时候,打印出一条信息,并对sum清零. 这种情况下,如果只用mutex, 则t3需要一个循环,每个循环里先取得lock_s,然后检查sum的状态,如果sum>=100,则打印并清零,然后unlock.如果sum& amp; amp; amp; lt;100,则unlock,并sleep()本线程合适的一段时间. 

     这个时候,t0,t1,t2的代码不变,t3的代码如下:

print() 
       while 
      
        pthread_mutex_lock(lock_s); 
        if(sum>=100) 
        
            printf(“sum reach 100!”); 
            pthread_mutex_unlock(lock_s); 
        
        else
        
            pthread_mutex_unlock(lock_s); 
            my_thread_sleep(100); 
            return 
        
    
}

这种办法有两个问题 
1) sum在大多数情况下不会到达100,那么对t3的代码来说,大多数情况下,走的是else分支,只是lock和unlock,然后sleep().这浪费了CPU处理时间. 
2) 为了节省CPU处理时间,t3会在探测到sum没到达100的时候sleep()一段时间.这样却又带来另外一个问题,亦即t3响应速度下降.可能在sum到达200的时候,t3才醒过来. 
3) 这样,程序员在设置sleep()时间的时候陷入两难境地,设置得太短了节省不了资源,太长了又降低响应速度.真是难办啊!

这个时候,condition variable内裤外穿,从天而降,拯救了焦头烂额的你. (抄袭的哈哈~)

  你首先定义一个condition variable. 
  pthread_cond_t cond_sum_ready=PTHREAD_COND_INITIALIZER; 
  t0,t1,t2的代码只要后面加两行,像这样

add()
{
    pthread_mutex_lock(lock_s);
    sum++;
    pthread_mutex_unlock(lock_s);
    if(sum>=100)
        pthread_cond_signal(&cond_sum_ready);
}
print()
{
    pthread_mutex_lock(lock_s);
    while(sum<100)
        pthread_cond_wait(&cond_sum_ready, &lock_s);
    printf(“sum is over 100!”);
    sum=0;
    pthread_mutex_unlock(lock_s);
    return;
}

注意两点:
1) 在thread_cond_wait()之前,必须先lock相关联的mutex, 因为假如目标条件未满足,pthread_cond_wait()实际上会unlock该mutex, 然后block,在目标条件满足后再重新lock该mutex, 然后返回.
2) 为什么是while(sum<100),而不是if(sum<100) ?这是因为在pthread_cond_signal()和pthread_cond_wait()返回之间,有时间差,假设在这个时间差内,还有另外一个线程t4又把sum减少到100以下了,那么t3在pthread_cond_wait()返回之后,显然应该再检查一遍sum的大小.
这就是用 while的用意


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值