我有一个程序,需要执行每X秒写一些输出。 程序将在每个输出之间进行一些间歇轮询和处理。 因此,例如我可能每5秒输出一次,但是我醒来后每隔1秒轮询一次,直到下一个5秒。 理论上这个程序在重启之间运行几个月,甚至更长。
我需要每X秒执行一次以保持与挂钟的一致性。 换句话说,我不能让时钟漂移,使我摆脱了第二个标记。 我不需要相当的准确性,但我想更频繁地轮询一秒钟,所以我需要一个结构,可以代表亚秒级的精确度。
我意识到,由于在操作系统上运行的本质,任何计时器的执行都会有一定的不一致/延迟,所以我不能确定我会在x秒内执行。 但是,只要它保持一个小的正态分布就没有问题,但我不想让漂移让时间持续越来越远。
我也希望尽可能地尽量减less轮询的CPU成本,但这是次要的问题。
什么时间结构可用于Linux,可以最好地提供我这个级别的精确性? 我试图避免包括由于分发麻烦在应用程序的提高,但可以使用它,如果我必须。 所以使用标准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,所以你执行。
这样你就不会在计数器中增加一个可能会有很大漂移的计数器,你计算的绝对是从一开始就计算的时间,所以你知道执行的确切时间。