gpt4 book ai didi

time - 如何使 pthread_cond_timedwait() 对系统时钟操作具有鲁棒性?

转载 作者:行者123 更新时间:2023-12-03 20:54:23 25 4
gpt4 key购买 nike

考虑以下完全符合 POSIX 标准的源代码:

#include <stdio.h>
#include <limits.h>
#include <stdint.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/time.h>

int main (int argc, char ** argv) {
pthread_cond_t c;
pthread_mutex_t m;
char printTime[UCHAR_MAX];

pthread_mutex_init(&m, NULL);
pthread_cond_init(&c, NULL);

for (;;) {
struct tm * tm;
struct timeval tv;
struct timespec ts;

gettimeofday(&tv, NULL);

printf("sleep (%ld)\n", (long)tv.tv_sec);
sleep(3);

tm = gmtime(&tv.tv_sec);
strftime(printTime, UCHAR_MAX, "%Y-%m-%d %H:%M:%S", tm);
printf("%s (%ld)\n", printTime, (long)tv.tv_sec);

ts.tv_sec = tv.tv_sec + 5;
ts.tv_nsec = tv.tv_usec * 1000;

pthread_mutex_lock(&m);
pthread_cond_timedwait(&c, &m, &ts);
pthread_mutex_unlock(&m);
}
return 0;
}

每 5 秒打印一次当前系统日期,但是,在获取当前系统时间 ( gettimeofday ) 和条件等待 ( pthread_cond_timedwait ) 之间会休眠 3 秒。

在打印“sleep (...)”之后,尝试将系统时钟设置为过去两天。发生什么了?好吧,不是像通常那样在条件下再等待 2 秒, pthread_cond_timedwait现在等待 两天 和 2 秒。

我该如何解决?
如何编写符合 POSIX 的代码,在用户操作系统时钟时不会中断?

请记住,即使没有用户交互,系统时钟也可能会发生变化(例如,NTP 客户端可能每天自动更新一次时钟)。将时钟设置为 future 没有问题,它只会导致 sleep 提早醒来,这通常没有问题,您可以轻松“检测”并相应地处理,但是将时钟设置为过去(例如因为它是在将来运行时,NTP 检测到并修复它)可能会导致一个大问题。

PS:
都没有 pthread_condattr_setclock()也不是 CLOCK_MONOTONIC存在于我的系统中。这些对于 POSIX 2008 规范(“Base”的一部分)是强制性的,但大多数系统截至今天仍然只遵循 POSIX 2004 规范,在 POSIX 2004 规范中,这两个是可选的(高级实时扩展)。

最佳答案

有趣的是,我以前没有遇到过这种行为,但是,再说一次,我没有那么多浪费系统时间的习惯:-)

假设你这样做是有正当理由的,一个可能的(虽然笨拙)的解决方案是让另一个线程,其唯一目的是定期踢条件变量以唤醒任何受影响的线程。

换句话说,类似于:

while (1) {
sleep (10);
pthread_cond_signal (&condVar);
}

等待条件变量被踢出的代码无论如何都应该检查其谓词(以处理虚假唤醒),因此这不应该对功能产生任何真正的不利影响。

这是一个轻微的性能损失,但每十秒一次应该不会有太大问题。它真的只是为了处理(无论出于何种原因)您的定时等待将等待很长时间的情况。

另一种可能性是重新设计您的应用程序,以便您根本不需要定时等待。

在由于某种原因需要唤醒线程的情况下,它总是由另一个线程完全有能力踢一个条件变量来唤醒一个(或广播来唤醒它们中的很多)。

这与我上面提到的踢脚线非常相似,但更多的是作为您的架构的一个组成部分,而不是一个 bolt 固定。

关于time - 如何使 pthread_cond_timedwait() 对系统时钟操作具有鲁棒性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7121212/

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