clock_gettime()每50-100毫秒返回1-2ms的不准确性(Debian在Virtualbox上运行)

我刚才在这里有一个密切相关的线程。

但是,用usleep(50e3)replacecin.ignore() usleep(50e3) 。 它不会每隔50毫秒报告一次。 时钟报告

 Time Passed: s: 0 ms: 50 Time Passed: s: 0 ms: 101 Time Passed: s: 0 ms: 152 Time Passed: s: 0 ms: 202 Time Passed: s: 0 ms: 252 Time Passed: s: 0 ms: 303 Time Passed: s: 0 ms: 353 Time Passed: s: 0 ms: 403 Time Passed: s: 0 ms: 454 Time Passed: s: 0 ms: 504 Time Passed: s: 0 ms: 554 Time Passed: s: 0 ms: 605 Time Passed: s: 0 ms: 657 Time Passed: s: 0 ms: 708 Time Passed: s: 0 ms: 758 Time Passed: s: 0 ms: 808 Time Passed: s: 0 ms: 862 Time Passed: s: 0 ms: 915 Time Passed: s: 0 ms: 965 Time Passed: s: 1 ms: 15 Time Passed: s: 1 ms: 66 Time Passed: s: 1 ms: 116 Time Passed: s: 1 ms: 169 Time Passed: s: 1 ms: 221 Time Passed: s: 1 ms: 271 Time Passed: s: 1 ms: 322 Time Passed: s: 1 ms: 372 Time Passed: s: 1 ms: 423 Time Passed: s: 1 ms: 473 Time Passed: s: 1 ms: 524 Time Passed: s: 1 ms: 574 Time Passed: s: 1 ms: 625 Time Passed: s: 1 ms: 676 Time Passed: s: 1 ms: 727 Time Passed: s: 1 ms: 778 Time Passed: s: 1 ms: 833 Time Passed: s: 1 ms: 883 Time Passed: s: 1 ms: 935 Time Passed: s: 1 ms: 986 Time Passed: s: 2 ms: 37 Time Passed: s: 2 ms: 91 Time Passed: s: 2 ms: 142 Time Passed: s: 2 ms: 192 Time Passed: s: 2 ms: 243 Time Passed: s: 2 ms: 294 Time Passed: s: 2 ms: 346 Time Passed: s: 2 ms: 396 Time Passed: s: 2 ms: 450 Time Passed: s: 2 ms: 501 Time Passed: s: 2 ms: 552 Time Passed: s: 2 ms: 602 Time Passed: s: 2 ms: 652 Time Passed: s: 2 ms: 703 Time Passed: s: 2 ms: 753 Time Passed: s: 2 ms: 804 Time Passed: s: 2 ms: 855 Time Passed: s: 2 ms: 906 Time Passed: s: 2 ms: 956 Time Passed: s: 3 ms: 7 Time Passed: s: 3 ms: 57 Time Passed: s: 3 ms: 107 Time Passed: s: 3 ms: 158 Time Passed: s: 3 ms: 208 Time Passed: s: 3 ms: 258 Time Passed: s: 3 ms: 315 Time Passed: s: 3 ms: 365 Time Passed: s: 3 ms: 416 Time Passed: s: 3 ms: 466 Time Passed: s: 3 ms: 517 Time Passed: s: 3 ms: 567 Time Passed: s: 3 ms: 618 Time Passed: s: 3 ms: 668 Time Passed: s: 3 ms: 719 Time Passed: s: 3 ms: 769 Time Passed: s: 3 ms: 824 Time Passed: s: 3 ms: 875 Time Passed: s: 3 ms: 926 Time Passed: s: 3 ms: 976 Time Passed: s: 4 ms: 27 Time Passed: s: 4 ms: 79 Time Passed: s: 4 ms: 129 Time Passed: s: 4 ms: 182 Time Passed: s: 4 ms: 233 Time Passed: s: 4 ms: 283 Time Passed: s: 4 ms: 334 Time Passed: s: 4 ms: 384 Time Passed: s: 4 ms: 436 Time Passed: s: 4 ms: 486 Time Passed: s: 4 ms: 537 Time Passed: s: 4 ms: 587 Time Passed: s: 4 ms: 638 Time Passed: s: 4 ms: 688 Time Passed: s: 4 ms: 739 Time Passed: s: 4 ms: 789 Time Passed: s: 4 ms: 844 Time Passed: s: 4 ms: 895 Time Passed: s: 4 ms: 946 Time Passed: s: 4 ms: 997 Time Passed: s: 5 ms: 47 Time Passed: s: 5 ms: 101 Time Passed: s: 5 ms: 151 Time Passed: s: 5 ms: 202 Time Passed: s: 5 ms: 252 Time Passed: s: 5 ms: 303 Time Passed: s: 5 ms: 354 Time Passed: s: 5 ms: 404 Time Passed: s: 5 ms: 455 

正如你所看到的(抱歉,但也许是一个长期的输出,但以防万一),目前存在一致的不准确。

为什么会这样呢,是什么影响呢,怎么能修好?

当您的进程通过调用sleep函数进入睡眠sleep ,系统调度程序将延迟唤醒,直到请求的时间耗尽为止。 之后,它可能会唤醒进程或可能需要更长的时间。

usleep()函数将导致调用线程暂停执行,直到参数useconds指定的实时微秒已经过去,或者信号传递给调用线程,并且其操作是调用捕获信号功能或终止进程。 由于系统调度其他活动,暂停时间可能比请求的要长。

许多操作系统不能保证在睡眠时间结束之后它们会唤醒进程。

这是因为即使在实时操作系统中睡眠的工作原因。

基本上,当你问“睡X时间”时,你不会问“X时间醒来”,而是“X时间之前不要打电话给我”。 这就是为什么时间依赖性编程如此困难,以及视频游戏编程为什么使用帧而不是ms的原因。

如果你的系统没有超载,而且运行时间太长,那么这个不准确的数字就不足以构成麻烦了。如果是这样的话,你需要另外一种方法来检查时间(可能是世界时?你将依赖于网络)。

数字刻度具有固有的量化不准确性(如在任何DAC / ADC中),这意味着对于1 ms持续时间的刻度,您的不准确度可以从“几乎0”到“几乎1 ms”。

有关MSDN文章的完美图片说明: 在这里输入图像描述

(是的,有时MSDN实际上有有用和有见地的文章)与这个文本:

“如果一个硬件生成器以一个恒定的速率提供刻度,那么可以通过简单地计数这些刻度来测量时间间隔,生成刻度的速率称为频率,用赫兹(Hz)表示,频率的倒数称为周期或时间间隔,并以适当的国际单位制(SI)时间单位(例如秒,毫秒,微秒或纳秒)表示时间间隔计时器的分辨率等于周期。能够区分任何两个时间戳,并在可测量的最小时间间隔上设置一个下限,这有时被称为时间分辨率(tick resolution),数字时间测量引入了±1滴答的测量不确定性,因为数字计数器以离散时间不断推进,这种不确定性被称为量化误差,对于典型的时间间隔测量,这种效应往往可以忽略,因为 e量化误差比测量的时间间隔小得多。“