Планирование Linux linux
Наш продукт работает под управлением Linux 2.6.32, и у нас есть некоторые процессы пользовательского пространства, которые периодически запускаются - процессы "как в жизни". Мы не предъявляем жестких требований к этим процессам - они просто должны запускаться раз в несколько секунд и обновлять сторожевой таймер.
Мы дали этим процессам класс планирования RR или FIFO с максимальным приоритетом, и все же мы видим много ложных срабатываний - кажется, что они не получают ЦП в течение нескольких секунд. Я нахожу это очень странным, потому что я знаю, что Linux, хотя и не является операционной системой RT, все же может давать очень хорошую производительность (я вижу, что люди говорят о порядках в несколько мс) - и я даже не могу заставить этот процесс запускаться раз в 5 сек.
Логика планировщика Linux RT кажется очень простой и простой, поэтому я подозревал, что эти процессы блокируются чем-то другим - конфликт ввода-вывода, прерывания или потоки ядра, занимающие слишком много времени - но теперь я не уверен: я написал действительно базовая программа для имитации такого процесса - она просыпается каждую 1 секунду и измеряет время, потраченное с момента последнего запуска. Насколько я понимаю, измерение времени не включает блокировку любого ввода-вывода, поэтому результаты, напечатанные этим процессом, отражают поведение планировщика:
#include <sched.h>
#include <stdio.h>
#include <sys/time.h>
#include <sys/param.h>
#include <time.h>
#define MICROSECONDSINASEC 1000000
#define MILLISECONDSINASEC 1000
int main()
{
struct sched_param schedParam;
struct timeval now, start;
int spent_time = 0;
time_t current_time;
schedParam.sched_priority = sched_get_priority_max(SCHED_RR);
int retVal = sched_setscheduler(0, SCHED_RR, &schedParam);
if (retVal != 0)
{
printf("failed setting RT sched");
return 0;
}
gettimeofday(&start, 0);
start.tv_sec -= 1;
start.tv_usec += MICROSECONDSINASEC;
while(1)
{
sleep(1);
gettimeofday(&now, 0);
now.tv_sec -= 1;
now.tv_usec += MICROSECONDSINASEC;
spent_time = MILLISECONDSINASEC * (now.tv_sec - start.tv_sec) + ((now.tv_usec - start.tv_usec) / MILLISECONDSINASEC);
FILE *fl = fopen("output_log.txt", "aw");
if (spent_time > 1100)
{
time(¤t_time);
fprintf(fl,"\n (%s) - had a gap of %d [msec] instead of 1000\n", ctime(¤t_time), spent_time);
}
fclose(fl);
gettimeofday(&start, 0);
}
return 0;
}
Я запустил этот процесс в одночасье на нескольких машинах - в том числе на тех, которые не запускают наш продукт (просто в Linux), и я все еще видел разрывы в несколько секунд - даже при том, что я убедился, что процесс получил приоритет - и я не могу понять почему - технически этот процесс должен предвосхитить любой другой запущенный процесс, так как же он может так долго ждать?
Несколько заметок:
- Я запускал эти процессы в основном на виртуальных машинах, так что, возможно, гипервизор может вмешаться. Но в прошлом я видел такое поведение и на физических машинах.
- Создание процесса RT действительно улучшило результаты, но не полностью предотвратило проблему.
- На машине не запущены никакие другие процессы RT, кроме процесса миграции в Linux и сторожевого таймера (который, я не верю, может вызвать голод в моих процессах).
Что я могу сделать? Я чувствую, что мне здесь чего-то не хватает.
Спасибо!