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);//themutexisunlockedoncethethreadgetsblocked
  9. //mutexislockedandownedbythecurrentthreadagain 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. //criticalsection
  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. //criticalsection
  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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值