那么pthread_cond_timedwait立即返回
-
20-08-2019 - |
题
我有一个奇怪的问题。我有以下代码:
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;
}
条件变量可以不合逻辑解除封锁。你需要检查它在一个循环,并通过每次检查条件。您可能会需要一并更新超时值。
我发现pthread_cond_timedwait
此处一些文档
当使用条件变量有 始终是一个布尔谓词 涉及相关的共享变量 与每个条件等待这是真的 如果线程应继续进行。伪 从唤醒 那么pthread_cond_timedwait()或 pthread_cond_wait()的功能可以 发生。由于从返回 那么pthread_cond_timedwait()或 调用pthread_cond_wait()并不意味着 关于这个的任何有价值的东西 谓语,谓语应 在这种返回重新评估。
由于已经在其他的答案中提到,你必须使用绝对时间。由于C11可以使用timespec_get()
。
struct timespec time;
timespec_get(&time, TIME_UTC);
time.tv_sec += 5;
pthread_cond_timedwait(&cond, &mutex, &time);