大多数Linux系统中的jiffies默认为250(4ms)。问题是,当程序的 usleep() 时间小于 4ms 时会发生什么?当然,它会按预定的方式运行。但是,当 Linux 调度程序因另一个程序必须运行而取出该程序等待时,会发生什么情况呢?在这种情况下抢占是如何工作的?
我应该避免等待时间这么短的自定义程序吗?他们不可能准确,不是吗?
答案1
看时间(7),以及它引用的联机帮助页。摘录:
High-Resolution Timers
Before Linux 2.6.21, the accuracy of timer and sleep system calls (see
below) was also limited by the size of the jiffy.
Since Linux 2.6.21, Linux supports high-resolution timers (HRTs),
optionally configurable via CONFIG_HIGH_RES_TIMERS. On a system that
supports HRTs, the accuracy of sleep and timer system calls is no
longer constrained by the jiffy, but instead can be as accurate as the
hardware allows (microsecond accuracy is typical of modern hardware).
You can determine whether high-resolution timers are supported by
checking the resolution returned by a call to clock_getres(2) or look‐
ing at the "resolution" entries in /proc/timer_list.
HRTs are not supported on all hardware architectures. (Support is pro‐
vided on x86, arm, and powerpc, among others.)
有一条评论说你睡不了那么短的时间。这是不正确的;使用 HRT,你可以。试试这个程序:
/* test_hrt.c */
#include <time.h>
main()
{
struct timespec ts;
int i;
ts.tv_sec = 0;
ts.tv_nsec = 500000; /* 0.5 milliseconds */
for (i = 0; i < 1000; i++) {
clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL);
}
}
编译它:
$ gcc -o test_hrt test_hrt.c -lrt
运行:
$ time ./test_hrt
real 0m0.598s
user 0m0.008s
sys 0m0.016s
正如您所看到的,0.5 毫秒延迟的 1000 次迭代仅花费了 0.5 秒多一点,正如预期的那样。如果clock_nanosleep
真的等到下一瞬间再回来的话,起码也需要4秒的时间。
现在最初的问题是,如果您的计划在那段时间被安排出来会发生什么?答案是,这取决于优先级。即使您的程序运行时另一个程序被调度,如果您的程序优先级较高,或者调度程序决定您的程序该运行了,那么它会在clock_nanosleep
超时返回后再次开始执行。它不需要等到下一个瞬间才会发生。您可以尝试在运行其他占用 CPU 的软件的同时运行上面的测试程序,您会发现它仍然以相同的时间执行,特别是如果您使用以下命令增加优先级:
$ time sudo schedtool -R -p 99 -e ./test_hrt
答案2
除非你运行的是实时内核,否则我无论如何都不会使用 < 10ms 的睡眠时间。即使调度程序愿意在超时时抢占另一个进程,抖动也可能会主导您的实际睡眠时间。
摘要:除非您有实时内核,否则请避免如此小的间隔。如果您无法更改内核,那么最好的选择可能是将您的进程固定到具有 SCHED_FIFO 的专用 CPU 上,并进行忙等待(或执行其他有用的工作),时间少于大约两个 jiffies。
不知怎的,摘要最终比原来的要长……哦,好吧。