注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

还东国的博客

行之苟有恒,久久自芬芳

 
 
 

日志

 
 

Linux中条件变量的超时等待  

2014-05-13 23:32:04|  分类: LINUX编程 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

Linux中条件变量的超时等待

用到了LINUX中的pthread_cond_timedwait,这个函数的本意是等待着信号量然后一定时间内如果等待不到,则自动返回超时,进入下一个动作,而不是始终阻塞在这个函数当前。这在某些情况下是非常有用的。

看一下这个函数的完整的声明:

int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime)

计时等待方式如果在给定时刻前条件没有满足,则返回ETIMEOUT,结束等待,其中abstime以与time()系统调用相同意义的绝对时间形式出现,0表示格林尼治时间197011000秒。
看红色的注释没有,这里就让人容易犯一个错,比如在C++C库里有一个数据结构time_t 使用这个数据结构定义数据,程序就几乎是立刻超时,也就是说达不到想要延时的目的。因为time_ttime()的用法混合后,就会产生上面所讲的立刻超时。所以正确的做法是:

   struct timespec timer;

    timer.tv_sec=time(NULL)+1;

timer.tv_nsec=0;

(或者:

        timespec timer;

        tim.tv_sec = time(nullptr);

        tim.tv_nsec = 100;

        tim.tv_sec +=1;

   ret=pthread_cond_timedwait(&(pnode->cond),&(pnode->mutex),&timer);

 

Time_t用法:http://blog.csdn.net/love_gaohz/article/details/6637625

 然后再转一篇错误的方法:

pthread_cond_timedwait时间设置 2,788 次查看      0

Tweet

最近在使用pthread_cond_timedwait的时候,发现当超时时间设置成1秒以下的值时,无法得到想要的效果,具体表现为,没有wait足够的时间就被唤醒,且返回值正确。首先来看一下pthread_cond_timedwait的原型:

 

#include <pthread.h>

int pthread_cond_timedwait(pthread_cond_t *restrict cond,

pthread_mutex_t *restrict mutex,

const struct timespec *restrict abstime);

 

abstime是一个绝对时间,struct timespce的原型为:

 

struct timespec

{

__time_t tv_sec;        /* Seconds. */

long int tv_nsec;       /* Nanoseconds. */

};

 

其中tv_sec是秒,tv_nsec是纳秒(即1000,000,000分之一秒)

 

那么,看一下我之前出错的代码:

 

struct timespec abstime;

abstime.tv_nsec = (timeout_ms % 1000) * 1000000;

abstime.tv_sec = time(NULL) + timeout_ms / 1000;

pthread_cond_timedwait(&_read_cond, &_read_mutex, &abstime);

 

以上代码有问题,主要是因为time(NULL)的返回结果的精度是秒级的,那么如果当前时间是m秒+n毫秒,那么实际等待的时间只是timeout_ms n,且还有可能发生n > timeout_ms的情况,这种情形下,如果这段代码处在一处while循环内,则会造成大量的pthread_cond_timedwait系统调用,并造成大量的context switch,系统CPU会占用很高。

 

正确的代码应该改为如下:

 

struct timespec abstime;

struct timeval now;

gettimeofday(&now, NULL);

int nsec = now.tv_usec * 1000 + (timeout_ms % 1000) * 1000000;

abstime.tv_nsec = nsec % 1000000000;

abstime.tv_sec = now.tv_sec + nsec / 1000000000 + timeout_ms / 1000;

 

pthread_cond_timedwait(&_read_cond, &_read_mutex, &abstime);

 

通过gettimeofday获得精确到微秒(1000,000分之一秒)的时间数据,并处理不足一秒加上超时时间超过一秒的情况(即tv_sec上需要加上nsec/1000000000)。

转载地址:http://www.agilephp.net/2012/07/pthread_cond_timedwait-abstime/

 

  评论这张
 
阅读(537)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017