我有一个奇怪的问题.我有以下代码:
dbg("condwait: timeout = %d, %d\n", abs_timeout->tv_sec, abs_timeout->tv_nsec); ret = pthread_cond_timedwait( &q->q_cond, &q->q_mtx, abs_timeout ); if (ret == ETIMEDOUT) { dbg("cond timed out\n"); return -ETIMEDOUT; }
dbg
gettimeofday
在每一行之前调用并在行前加上时间.它产生以下输出:
7.991151: condwait: timeout = 5, 705032704 7.991158: cond timed out
如您所见,两个调试行之间只传递了7微秒,但仍然pthread_cond_timedwait
返回ETIMEDOUT
.怎么会发生这种情况?我甚至尝试在初始化cond变量时将时钟设置为其他内容:
int ret; ret = pthread_condattr_init(&attributes); if (ret != 0) printf("CONDATTR INIT FAILED: %d\n", ret); ret = pthread_condattr_setclock(&attributes, CLOCK_REALTIME); if (ret != 0) printf("SETCLOCK FAILED: %d\n", ret); ret = pthread_cond_init( &q->q_cond, &attributes ); if (ret != 0) printf("COND INIT FAILED: %d\n", ret);
(没有打印出任何错误消息).我想这两个CLOCK_REALTIME
和CLOCK_MONOTONIC
.
此代码是阻塞队列的一部分.我需要这样的功能,如果在5秒内没有任何东西放在这个队列上,就会发生其他事情.互斥锁和cond都被初始化,因为如果我不使用阻塞队列就可以正常工作pthread_cond_timedwait
.
pthread_cond_timedwait需要一个绝对时间,而不是相对时间.您需要通过将当前时间添加到超时值来使您的等待时间绝对.
溢出timespec
通常是奇怪超时的罪魁祸首.
检查EINVAL:
void timespec_add(struct timespec* a, struct timespec* b, struct timespec* out) { time_t sec = a->tv_sec + b->tv_sec; long nsec = a->tv_nsec + b->tv_nsec; sec += nsec / 1000000000L; nsec = nsec % 1000000000L; out->tv_sec = sec; out->tv_nsec = nsec; }