Linux/c++ 定时方法,尽管有漂移,但每 N 秒执行一次
Linux/c++ timing method to gaurentee execution every N seconds despite drift?
我有一个程序需要每X秒执行一次才能写入一些输出。 程序将在每个输出之间进行一些间歇性的轮询和处理。 例如,我可能每 5 秒输出一次,但我每 .1 秒醒来轮询一次,直到达到下一个 5 秒标记。 理论上,该程序将在重新启动之间运行数月,甚至可能更长。
我需要每 X 秒执行一次以与挂钟保持一致。 换句话说,我不能让时钟漂移导致我偏离X秒标记。 在间歇轮询中,我不需要完全相同的准确性,但我想更频繁地轮询一秒,所以我需要一个可以表示亚秒级精度的结构。
我意识到,由于在操作系统上运行的本质,任何计时器的执行都会有一定的不一致/延迟,以至于我无法确定我将在 x 秒内执行。 但是只要它保持较小的正态分布,这很好,我不希望漂移让时间持续变得越来越远。
我也希望尽可能降低轮询的 CPU 成本,但这是次要问题。
Linux 有哪些时序结构可以最好地为我提供这种级别的精确度? 由于分发中的麻烦,我试图避免在应用程序中包含 boost,但如果有必要,我可以使用它。 因此,使用标准 c++ 库的方法更受欢迎,但如果 Bosst 可以做得更好,我也想知道这一点。
谢谢。
-ps,我不能使用 c++11。 这不是一个选项,所以我无法使用它的任何构造。
clock_gettime和clock_nanosleep都以亚秒为单位运行,使用CLOCK_MONOTONIC
应该可以防止由于调整系统时间(例如NTP或adjtimex)而导致的任何偏差。 例如
long delay_ns = 250000000;
struct timespec next;
clock_gettime(CLOCK_MONOTONIC, &next);
while (1) {
next.ts_nsec += delay_ns;
next.ts_sec += ts_nsec / 1000000000;
next.ts_nsec %= 1000000000;
clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &next, NULL);
/* do something after the wait */
}
实际上,您应该检查您是否由于信号而提前返回,以及是否应该跳过间隔,因为您在睡觉时经过了太多时间。
其他睡眠方法,例如 nanosleep 和 select,只允许指定时间间隔并使用 CLOCK_REALTIME
,这是系统时间,可能会发生变化。
如果您需要一些没有抖动或时钟漂移的精确计时,请确保有一个外部时间源,如GPS,原子钟或无线电时钟。例如,请参阅此 PDF 中记录的 NTP 集成。所有NTP技巧在Linux和NanoBSD(在PDF中)上都有效。
我会记录我开始时t_0
的时间,然后在任何给定的时间t
,如果i = (t - t_0)/X
(整数除法)大于上次执行时的相同数量,则再次执行。
例如,假设您每 5 秒运行一次,如果您在时间 23 开始,则记录i = 0, t_0 = 23
。然后在时间 27,(27 - 23)/5 = 0
,所以你还没有执行。但是下次当涉及到时间 28 时,(28 - 23)/5 = 1
,它大于 0,所以你执行。
就不会将每个可能具有巨大漂移的即时报价添加到计数器中,而是绝对计算自开始以来的时间,因此您知道执行的确切时间。
- 为什么我的信号处理程序只执行一次?
- For循环在cpp中仅执行一次
- 在可变函数调用中执行一次语句
- cppUnit:针对多个测试方法执行一次的设置函数
- For 循环是否总是至少执行一次?
- 如何确保方法在该对象的生存期内仅执行一次?
- 线程仅执行一次
- while(getline(myReadFile, temp, ':')) 执行一次迭代太多导致向量越界
- Qt - 解决一个插槽上的两个顺序调用,并且仅执行一次操作
- 函数执行一次
- 共享/独占锁定,其中共享工作只能执行一次
- C++执行一次序列的最佳方法
- Linux/c++ 定时方法,尽管有漂移,但每 N 秒执行一次
- 每 t 毫秒执行一次 c++ 代码
- Winsock:回显服务器回复两次,当时我刚刚将其编程为执行一次send()调用
- 我在循环时遇到困难。它只执行一次
- QTimer 每秒执行一次方法
- 阿西奥:为什么计时器只执行一次
- 每秒执行一次的函数,它是有效的,但喜欢每0.5秒执行一次
- 在没有默认构造函数的OpenMP中,每个线程执行一次代码