gpt4 book ai didi

c++ - 带有单体定时器的 pthread_cond_timedwait 有时超时比预期晚

转载 作者:太空宇宙 更新时间:2023-11-03 17:24:46 24 4
gpt4 key购买 nike

我将 pthread_cond_timedwait 与单片定时器一起使用。我想问一下我的示例中是否存在问题或原因是什么,有时 pthread_cond_timedwait 等待的时间超过指定的超时时间(示例中为 300 毫秒)。

示例如下:

#include <pthread.h>
#include <iostream>
#include <ctime>

pthread_cond_t cond;
pthread_condattr_t cond_attr;
pthread_mutex_t mutex;

void *thread1(void *attr)
{
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
//fprintf(stderr, "starting timer for %ds, %dms\n", (period/1000), (period % 1000));

auto period = 300;
auto sec = (period / 1000);
auto nsec = (period % 1000) * 1000000;
fprintf(stderr, "[start] ts.sec=%d ts.ns = %d\n", ts.tv_sec, ts.tv_nsec);
if ((ts.tv_nsec + nsec) > 999999999)
{
ts.tv_sec += sec + 1;
ts.tv_nsec = nsec - (1000000000 - ts.tv_nsec);
fprintf(stderr, "[expected end] ts.sec=%d ts.ns = %d\n", ts.tv_sec, ts.tv_nsec);
//fprintf(stderr, "timeout = %dms\n", (sec * 1000) + ((1000000000 - ts_now.tv_nsec + ts.tv_nsec)/1000000));
}
else
{
ts.tv_sec += sec;
ts.tv_nsec += nsec;
fprintf(stderr, "[expected end] ts.sec=%d ts.ns = %d\n", ts.tv_sec, ts.tv_nsec);
//fprintf(stderr, "timeout = %dms\n", (sec * 1000) + ((ts.tv_nsec - ts_now.tv_nsec) / 1000000));
}
while (true)
{
auto ret = pthread_cond_timedwait(&cond, &mutex, &ts);
if (ret == ETIMEDOUT)
{
struct timespec ts2;
clock_gettime(CLOCK_MONOTONIC, &ts2);

fprintf(stderr, "[end] ts.sec=%d ts.ns = %d\n", ts2.tv_sec, ts2.tv_nsec);
auto seconds = ts2.tv_sec - ts.tv_sec;
auto nseconds = ts2.tv_nsec - ts.tv_nsec;
if (nseconds < 0)
{
seconds--;
nseconds = 1000000000 - nseconds;
}
fprintf(stderr, "[end] diff = %dms\n", (seconds * 1000) + (nseconds / 1000000));
break;
}
if (ret != 0)
{
fprintf(stderr, "ret: %m\n");
}
}
return nullptr;
}

int main()
{
pthread_t tid1;

pthread_mutex_init(&mutex, nullptr);
pthread_condattr_init(&cond_attr);
pthread_condattr_setclock(&cond_attr, CLOCK_MONOTONIC);
pthread_cond_init(&cond, &cond_attr);

pthread_create(&tid1, nullptr, thread1, nullptr);

pthread_join(tid1, nullptr);

return 0;
}

编译:

g++ -std=c++11 main.cpp -lpthread

输出:

dev@ pthread $./a.out
[start] ts.sec=58842 ts.ns = 602310036
[expected end]: ts.sec=58842 ts.ns = 902310036
[end] ts.sec=58842 ts.ns = 903171492
[end] diff = 0ms
dev@ pthread $./a.out
[start] ts.sec=58844 ts.ns = 378002207
[expected end]: ts.sec=58844 ts.ns = 678002207
[end] ts.sec=58844 ts.ns = 799322723
[end] diff = 121ms

最佳答案

您正在通过调用 pthread_cond_timedwait() 来调用未定义的行为,而没有锁定关联的互斥量。

POSIX documentation for pthread_cond_timedwait()状态:

DESCRIPTION

The pthread_cond_timedwait() and pthread_cond_wait() functions shall block on a condition variable. The application shall ensure that these functions are called with mutex locked by the calling thread; otherwise, an error (for PTHREAD_MUTEX_ERRORCHECK and robust mutexes) or undefined behavior (for other mutexes) results.

任何时序问题很容易是这种未定义行为的“奇怪”结果。

并且如评论中所述,无法保证错误返回的速度有多快。

关于c++ - 带有单体定时器的 pthread_cond_timedwait 有时超时比预期晚,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59667156/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com