pthread_cond_timedwait时间设置

最近在使用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)。

2012年7月19日 | 归档于 C++, Linux, 技术
本文目前尚无任何评论.

发表评论

XHTML: 您可以使用这些标签: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">