pthread_cond_wait/pthread_cond_timedwait使用注意


今天在阅读Linux Device Drivers时,读到了如下一段话:
Another thing to remember with sleeping is that, when you wake up, you never know how long your process may have been out of the CPU or what may have changed in the mean time. You also do not usually know if another process may have been sleeping for the same event; that process may wake before you and grab whatever resource you were waiting for. The end result is that you can make no assumptions about the state of the system after you wake up, and you must check to ensure that the condition you were waiting for is, indeed, true.

大意即是说,当在睡眠等待醒来后,不应该想当然地对当前系统状态做出任何假定。比如你在进入睡眠等待某个资源时,醒后不能假定这个资源就一定处于可用状态,仍需再次进行判断。因为有可能你等待的资源已经就绪,但是有一个线程之前也在等待该资源,而且先于本线程唤醒而拿到了那个资源,这样以来当你醒来时又扑了个空。联想起linux编程时经常会用到的pthread_cond_wait()函数在使用时的一个坑。下面来看一段典型的错误代码:
//
// 错误条件等待的编程方式!无论c、java!!
pthread_mutex_lock(&t.mn);
t.waiters++;
clock_gettime(CLOCK_REALTIME, &ts);
ts.tv_sec += 5;

rc = pthread_cond_timedwait(&t.cond, &t.mn, &ts);  // 等待ts的时间间隔
t.waiters--;

if (rc == 0) setmystate(&t);  // 等待位超时,执行相应动作
pthread_mutex_unlock(&t.mn);

上面的例子中,pthread_cond_timedwait()在没有超时就醒来后,也不一定是等到了预期的条件!线程可能因为其他奇怪的原因而唤醒!简言之,等待醒来,不等于条件已经满足。正确的处理方式应该如下:
//
//条件等待的编程范式,无论c、java
pthread_mutex_lock(&t.mn);
t.waiters++;
clock_gettime(CLOCK_REALTIME, &ts);
ts.tv_sec += 5;

rc = 0;
while (! mypredicate(&t) && rc == 0) // 唤醒后再次检查预期条件是否满足
    rc = pthread_cond_timedwait(&t.cond, &t.mn, &ts);
t.waiters--;

if (rc == 0)
    setmystate(&t);
pthread_mutex_unlock(&t.mn);</span></span></span>

代码中,调用pthread_cond_timedwait()醒来后,再次使用pypredicate()检查了是否预期的条件已经满足。如果条件仍未满足,而且等待亦未超时(即pthread_cond_wait返回0),那么这是一次意外的提前唤醒,需要再次进入pthread_cond_timedwait()睡眠等待。这样当最终跳出while循环时如果仍未超时,那么就一定是等到了预期的条件。

小结:知识的积累是一个越来越快的加速过程,只有知道了很多,积累了足够的经验,才能知道更多更多。当积累了很多的东西,读一本书,不经意间随手都有收获。尤其是重读经典。此外,也应该多发问,多思考多问为什么,这样成长才能加速度。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值