很久以前,我的程序中有一个错误。根本原因是 C 函数
sleep(60);
在极少数情况下睡眠时间少于 60 秒。或者该功能确实导致线程休眠超过 60 秒,但操作系统会自动更改时钟(这似乎可能是因为错误仅在 XX::00::00
上发生),也就是它很少出现,并且仅在"圆形小时"(睡眠应该在>xh0m0s 结束,它在 x-1h59m59.99*s
结束)。
然后我的项目经理继续咆哮,他说了一百万次,我们应该只使用计时器,而不是睡眠。从那时起,我接受了计时器比sleep()更准确的观念,但现在我觉得我应该要求一些更权威的来源。所以:
- 计时器比睡眠更精确吗? (
- 相关)它们是否在内心深处(在操作系统级别)使用不同的方法实现?
我知道计时器是用来做回调的,睡眠只是延迟当前线程的执行,我说的是延迟执行部分的实现。
是Linux,但如果可能的话,我关心一般答案。
计时器绝对比睡眠更准确。睡眠只是对任务计划程序恢复线程或进程之前多长时间的粗略度量。对系统时钟、超载任务计划程序等的更改将影响睡眠的实际睡眠时间。
计时器将更准确地测量时间。一般来说,计时器会准确地测量时间。有两种计时器 - 一种基于系统时钟,如"time.h"中的函数。这些将受到系统时钟更改等因素的影响。例如,如果您更改系统时间、从夏令时切换或暂停机器等,实际测量时间可能与实时不同。
另一种时钟是基于 CPU 时钟周期的高分辨率计时器。这些计时器类似于Windows上的QueryPerformanceTimer和Linux上的clock_gettime()。这些只是计算 CPU 周期。它们不会受到系统计时器更改的影响 - 但它们将以两种方式偏离现实世界的时间:
- 时间
- 会在很长一段时间内倾斜,因为时钟分辨率不精确,以至于长时间以这种方式测量时间会导致 CPU 时间偏离实时。
- 如果计算机挂起,CPU 将停止,计时器不会考虑这一点。
您要做的是睡眠时间短得多,并使用具有适当分辨率的时钟。例如。如果您需要睡眠时间少于几分钟,则应使用高分辨率计时器。睡眠频率比您需要的多 100 倍,并在每次睡眠恢复时检查经过的时间,看看是否经过了正确的时间。如果您需要睡眠超过几分钟,请执行相同的操作,但使用time.h中的函数来检查经过的时间。
如果您需要100%准确地使用时间,您可能需要专门的硬件 - 或者定期根据在线时间服务器检查实时时间 - 例如海军的原子钟。( http://tycho.usno.navy.mil/ntp.html)
没有通用的答案,原因很简单,C 或 C++ 标准中都没有提供使应用程序进入睡眠状态的能力。因此,讨论本质上将依赖于操作系统。
Unix sleep()
函数具有粗粒度。还有具有更精细粒度的usleep()
和nanosleep()
。函数select()
还可用于使应用程序进入睡眠状态。只需指定超时,无需文件描述符。
注意 #1:未指定sleep()
、usleep()
、nanosleep()
、定时器和警报之间的交互。
注意#2:不要指望这些机制中的任何一个具有原子钟的精度。