zoukankan      html  css  js  c++  java
  • pthread_cond_timedwait时间设置

    最近工作中需要在ACodec中起一个pthread,并每间隔100ms统计一次buffer的状态,在程序中使用pthread_cond_timedwait来设置时间间隔,但在使用中发现当超时时间设置成1秒以下的值时,无法得到想要的效果,具体表现为,没有wait足够的时间就被唤醒,且返回值正确。

    查看pthread_cond_timedwait的函数原型:

    1 int pthread_cond_timedwait(pthread_cond_t *cond_interface,
    2                            pthread_mutex_t * mutex,
    3                            const timespec *abstime)

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

    1 struct timespec {
    2   time_t tv_sec;    /* Seconds */
    3   long tv_nsec;     /* Nanoseconds */
    4 };

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

    首先看一下我之前错误的代码:

    1 long timeout_ms = 100; // wait time 100ms
    2 struct timespec abstime;
    3 abstime.tv_sec = time(NULL) + timeout_ms / 1000;
    4 abstime.tv_nsec = (timeout_ms % 1000) * 1000000;
    5 pthread_cond_timedwait(&cond, &mutex, &abstime);

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

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

    1 struct timespec abstime;
    2 struct timeval now;
    3 long timeout_ms = 100; // wait time 100ms
    4 gettimeofday(&now, NULL);
    5 long nsec = now.tv_usec * 1000 + (timeout_ms % 1000) * 1000000;
    6 abstime.tv_sec=now.tv_sec + nsec / 1000000000 + timeout_ms / 1000;
    7 abstime.tv_nsec=nsec % 1000000000;
    8 pthread_cond_timedwait(&cond, &mutex, &abstime); 

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

  • 相关阅读:
    css权重
    面试题目之 怪异模式和严格模式
    写点东西,以便回忆-2014最后一天,安好
    background-position 用法详细介绍
    css样式自动换行/强制换行
    浏览器兼容之Chrome浏览器: -webkit-text-size-adjust: none;
    html5常用基本标签
    css样式编辑
    Bootstrap 基本用法(续)
    Bootstrap 基本用法
  • 原文地址:https://www.cnblogs.com/roger-yu/p/6163712.html
Copyright © 2011-2022 走看看