当程序的计时器小于 4 毫秒时,抢占在 Linux 上如何工作?

当程序的计时器小于 4 毫秒时,抢占在 Linux 上如何工作?

大多数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。

不知怎的,摘要最终比原来的要长……哦,好吧。

相关内容