关于如何使用pthread_cond_timedwait()超时接口

之前大家讨论说pthread_cond_timedwait()接口不能用,如果需要超时返回功能的话必须写一个定时器来实现.但是该操作太昂贵了,其实可以直接使用该接口来实现超时等待功能的,下面描述我对该接口的了解及用法,仅供参考.

1.    POSIX提供了多种时钟类型,其中包括以下两种:
CLOCK_REALTIME: Systemwide realtime clock. 系统范围内的实时时钟,是个软件时钟,可以通过命令等方式修改该系统时间.
CLOCK_MONOTONIC:Represents monotonic time. Cannot be set. 表示单调时间,为系统起机时到现在的时间,不能被设置跟修改.

pthread_cond_timedwait()在没有设置条件变量属性的时候,默认用的是CLOCK_REALTIME软件时间,因此在极端情况下会出现实际等待的时间与设置的超时时间不同.
下面介绍下如何正确使用pthread_cond_timedwait()接口

2.    正确使用pthread_cond_timedwait()接口方式即将测量时间参照改为CLOCK_MONOTONIC,这个需要在初始化时设置条件变量的属性,之后再设置超时时间.例子如下:
    ret = pthread_condattr_init(&(pthread_info.condattr));
    if (ret != 0) {
        exit(1);
    }
ret = pthread_condattr_setclock(&(pthread_info.condattr), CLOCK_MONOTONIC);

ret = pthread_cond_init(&(pthread_info.cleanup_queue_wait), &(pthread_info.condattr));

struct timespec tv;
clock_gettime(CLOCK_MONOTONIC, &tv);
PTHREAD_TASK_DBG(LOGS_DEBUG, "now time:%d\n", tv.tv_sec);
tv.tv_sec += 30;-这里设置30秒后没收到事件超时返回
ret = pthread_cond_timedwait(&(pthread_info.cleanup_queue_wait), &(pthread_info.cleanup_queue_lock), &tv);


运行如下:


从上可以看出,使用该方式无论对系统时间设置为任何值时,系统运行时间都不会被修订,同时该线程也不会被触发返回,依旧是原先的30秒超时.

3.    其实使用CLOCK_REALTIME作为测量时间参照也是可行的,只是在极端的情况下(如在获取当前系统时间后系统时间马上被修订)时,这个超时时间就不正确了,不过这是小概率事件.
例子如下:
struct timespec tv;
tv.tv_sec = time(NULL);-极端情况下在获取当前系统时间后系统时间马上被修订
PTHREAD_TASK_DBG(LOGS_DEBUG, "now time:%d\n", tv.tv_sec);
tv.tv_sec += 30;-这里设置30秒后没收到事件超时返回
ret = pthread_cond_timedwait(&(pthread_info.cleanup_queue_wait), &(pthread_info.cleanup_queue_lock), &tv);

运行如下:
 


从上面可以看出,使用该方式在线程进入超时等待后,无论将系统时间改成以前后以后的时间,time(NULL)会返回当前设置后的时间,但线程都不会被触发返回.

4.    参考资料:
http://man.chinaunix.net/unix/susv3/functions/pthread_condattr_setclock.html
http://man.chinaunix.net/unix/susv3/functions/pthread_cond_timedwait.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值