POSIX Thread相关

1. 关于pthread_cond系列函数

pthread_cond_wait的参数里有一个mutex,其作用往往令人费解。

最近在考察OpenMAX系统发现这一部分的实现可能导致较大的风险。

一般而言有了这个mutex以后对于cond实现一些增强的特性就比较方便。

例如,如果要将cond用作semaphore,以下代码应该能起作用:

  1. sem_down(sem)
  2. {
  3.     pthread_mutex_lock(sem->mutex);
  4.     // critical section  
  5.     sem->count--;
  6.     if (sem->count < 0)
  7.     {
  8.         pthread_cond_wait(sem->cond, sem->mutex);    // the mutex is unlocked once the thread gets blocked
  9.         // mutex is locked and owned by the current thread again after it is scheduled to run when unblocked
  10.     }
  11.     pthread_mutex_unlock(sem->mutex)
  12. }
  13. sem_up(sem)
  14. {
  15.     pthread_mutex_lock(sem->mutex);    // absence of this mutex acquisition may cause severe error
  16.     sem->count++;
  17.     pthread_cond_signal(sem->cond);
  18.     pthread_mutex_unlock(sem->mutex)
  19. }

这样cond和count的操作被完全保护(原子化),同时由于pthread_cond_wait在cond阻塞情况下自动释放mutex又不至于导致死锁。

但是其前提条件是底层的OS正确地实现这几个POSIX接口的意图(这不是必然的)。否则需要通过时序的分析确定可能造成的问题。

注意在sem_up中如果不做互斥量保护则在如下情况下发生错误:

线程A阻塞在pthread_cond_wait,sem->count计数为-1;

线程B进入sem_down,并执行完成sem->count--后,调度到线程C;

线程C进入sem_up,执行sem->count++,和pthread_cond_signal,使得sem->count计数变为0,同时线程A被激活;

这样线程A可获得mutex并从sem_down返回;

线程B条件判断不成立不被阻塞,亦返回。但显然在这个序列中应该至少有一个线程被阻塞。(按理想顺序应该B被阻塞)

 

由于posix规定中关于pthread_cond_signal触发的说明是至少释放一个阻塞,于是存在同时释放多个阻塞的情形。如下代码也许可以解决这个问题:

  1. sem_down(sem)
  2. {
  3.     pthread_mutex_lock(sem->mutex);
  4.     // critical section   
  5.     sem->count--;
  6.     if (sem->count < 0)
  7.     {
  8. _again:
  9.         sem->nblocked++;    // count the number of blocked threads   
  10.         pthread_cond_wait(sem->cond, sem->mutex); 
  11.         sem->nblocked--;
  12.         if (sem->nblocked + sem->count < 0)
  13.         {    // this thread is not ready to be unblocked
  14.             goto _again;
  15.         }
  16.     }
  17.     pthread_mutex_unlock(sem->mutex);
  18. }

如果count不记录被阻塞的线程个数,以下方案很理想:

  1. sem_down(sem)
  2. {
  3.     pthread_mutex_lock(sem->mutex);
  4.     // critical section    
  5.     while(sem->count == 0)
  6.     {
  7.         pthread_cond_wait(sem->cond, sem->mutex); 
  8.     }
  9.     sem->count--;
  10.     pthread_mutex_unlock(sem->mutex);
  11. }

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值