我有一个奇怪的问题。我有以下代码:

    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_REALTIMECLOCK_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);
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top