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

2024-02-03

考虑以下完全符合 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 秒打印一次当前系统日期,但是,在获取当前系统时间之间会睡眠 3 秒(gettimeofday)和条件等待(pthread_cond_timedwait).

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

我该如何解决这个问题?
如何编写 POSIX 兼容的代码,使其在用户操作系统时钟时不会中断?

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

PS:
两者都不pthread_condattr_setclock() nor CLOCK_MONOTONIC存在于我的系统上。这些对于 POSIX 2008 规范(“Base”的一部分)来说是强制性的,但大多数系统迄今为止仍然只遵循 POSIX 2004 规范,并且在 POSIX 2004 规范中,这两个是可选的(高级实时扩展)。


有趣的是,我以前没有遇到过这种行为,但是话又说回来,我没有那么多乱搞系统时间的习惯:-)

假设您出于正当理由这样做,一种可能的(尽管很笨拙)解决方案是使用另一个线程,其唯一目的是定期启动条件变量以唤醒任何受影响的线程。

换句话说,类似:

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

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

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


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

在出于某种原因需要唤醒线程的情况下,它总是由另一个线程完全能够启动条件变量来唤醒一个线程(或通过广播来唤醒许多线程)。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使 pthread_cond_timedwait() 对系统时钟操作具有鲁棒性? 的相关文章

  • pthread_join() 中的阻塞

    根据手册页 pthread join 函数应暂停调用的执行 线程直到目标线程终止 除非目标线程 已经终止了 因此 据我了解 调用进程将阻塞 直到指定的线程退出 现在考虑以下代码 pthread t thrs NUMTHREADS for i
  • 同步通过 LAN 电缆连接的两台 Windows 7 计算机之间的时间

    我有许多笔记本电脑 它们运行我们的应用程序 同时通过以太网电缆成对连接 但未连接到任何外部网络或互联网 时间 我需要连接对来同步其系统时间 但由于每台计算机都需要能够与任何其他计算机同步 因此我无法将一台计算机定义为时间服务器 而另一台计算
  • PHP 日期/时间格式,需要一些帮助

    你能帮我使用 PHP 格式化以下日期吗 变量 start 包含以下日期 这个日期 Wed Feb 01 2012 05 00 00 GMT 080 应该成为 2012 02 01T13 00 00 我知道如何使用基本的 PHP 日期 时间格
  • 建议一种每分钟更新时间的方法

    我有一个完整的ajax应用程序 我正在使用下面的代码每分钟更新一次时间 但如果我保持浏览器打开超过 10 分钟 浏览器就会变得无响应 缓慢 建议更好的代码 function tick var d new Date var time padN
  • 哪些语言可以很好地进行日期、时间和日历操作? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 这可能是一个过分的要求 但是有没有一种语言能够真正出色地表示时间和日期操作呢 我会立即承认这是真的很难编写一个真正伟大的时间库 也就是
  • Ruby 中的日期时间和时间之间的转换

    在 Ruby 中如何在 DateTime 和 Time 对象之间进行转换 require time require date t Time now d DateTime now dd DateTime parse t to s tt Tim
  • time() 会返回相同的输出吗?

    当用户注册时 我正在为 PHP 中的用户生成令牌 我想知道两个用户是否可以获得相同的令牌 因为这会破坏系统 请让我知道这是否足够 token md5 rand time 编辑 我现在正在使用我在另一个问题上找到的generate uuid
  • 使用多线程的套接字服务器或文件服务器实现:概念不清楚

    请帮我理清这个概念 假设我们有一个使用线程实现的套接字端口服务器 套接字服务器侦听套接字端口 并在消息到达时创建一个线程来服务该请求 客户端代码向服务器发送给定数量的消息 该客户端代码也可以由多个用户在不同的计算机上运行 我知道客户端代码作
  • 将纪元时间转换为日期 PHP

    我现在正在使用一个 API 它提供了一个 epochTime 我已尝试一切方法将此纪元转换为日期 但它似乎不起作用 包括 epoch time 1000然后使用date 函数来转换它 纪元时间看起来像这样 1353430853299 有办法
  • 数百个空闲线程的影响

    我正在考虑使用可能数百个线程来实现通过网络管理设备的任务 这是一个在带有 Linux 内核的 powerpc 处理器上运行的 C 应用程序 在每个任务进行同步以将数据从设备复制到任务的初始阶段之后 任务变得空闲 并且仅在收到警报或需要更改一
  • 将年月(“yyyy-mm”格式)转换为日期?

    我有一个如下所示的数据集 Month count 2009 01 12 2009 02 310 2009 03 2379 2009 04 234 2009 05 14 2009 08 1 2009 09 34 2009 10 2386 我想
  • 计时器显示负的已用时间

    我正在使用一个非常简单的代码来计算每个循环的时间for陈述 它看起来像这样 import time for item in list of files Start timing this loop start time clock Do a
  • 使用 System.currentTimeMillis() 每秒运行一次代码

    我试图使用 System currentTimeMillis 每秒运行一行代码 代码 while true long var System currentTimeMillis 1000 double var2 var 2 if var2 1
  • 如何确定算法函数的复杂度?

    您如何知道算法函数对于特定操作是否需要线性 常数 对数时间 它取决于CPU周期吗 您可以通过三种方式 至少 做到这一点 在网上查找算法 看看它是如何描述其时间复杂度的 根据输入大小 自己检查算法 查看嵌套循环和递归条件等内容 以及每个循环运
  • 从 varchar(100) 类型获取时间(HH:MM AM/PM)格式

    如何将字符串 RD OT 07 30 转换为时间 我只知道如何将 07 30 AM 转换为时间 下面的代码给了我一个空白数据 id strtoupper POST id query mysql query SELECT STR TO DAT
  • 处理 C++ 中执行时间的大量分析

    我目前正在进行一个科学计算项目 涉及海量数据和复杂算法 因此需要进行大量代码分析 我目前依靠的是
  • 下拉 24 小时选项值和 12 小时显示

    我需要创建一个时间数组 以便在 HTML 下拉列表中使用 数组键应采用 24 小时格式 值应采用 12 小时制 包含 am 和 pm 在数据库中我想存储 24 小时格式 有没有一种快速的方法来创建数组而不是每小时键入 example 00
  • 何时使用 pthread 条件变量?

    线程问题 看来 只有在其他线程调用 pthread cond notify 之前调用 pthread cond wait 时 条件变量才起作用 如果在等待之前发生通知 那么等待将被卡住 我的问题是 什么时候应该使用条件变量 调度程序可以抢占
  • 计算轮班工作时间并检测

    我有个问题 我的英语很差 我需要用PHP做一个加班计算 已经有一个代码可以实现这一点 但当工作时间超过2天时 计算就会出错 工作开始 2018 09 09 13 43 工作结束 2018 09 11 07 13 结果 07 18 04 00
  • 在java中创建Unix时间戳[重复]

    这个问题在这里已经有答案了 可能的重复 从 Date 获取 Unix 时间戳 https stackoverflow com questions 7784421 getting unix timestamp from date 我正在约会

随机推荐