pthread_cond_timedwait时间设置
Posted Hi,出发了
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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)。
以上是关于pthread_cond_timedwait时间设置的主要内容,如果未能解决你的问题,请参考以下文章
JNI 环境中 pthread_cond_broadcast() 和 pthread_cond_timedwait() 的等效函数是啥?
pthread_cond_timedwait超时后,线程是否拥有互斥锁?
Linux多线程编程 - sleep 和 pthread_cond_timedwait
Linux C语言 pthread_cond_wait()pthread_cond_timedwait()函数(不允许cond被唤醒时产生竞争,所以需要和互斥锁搭配)