Linux, нужно точное время программы. Планировщик просыпается программа

У меня есть поток, работающий на Linux-системе, который мне нужно выполнить с точностью до интервалов. Например. выполнить один раз каждые ms.

В настоящее время это делается путем создания таймера с

 timerfd_create(CLOCK_MONOTONIC, 0)

а затем передав требуемое время сна в структуре с помощью

 timerfd_settime (fd, 0, &itval, NULL);

На этом таймере выполняется блокирующий вызов чтения, который останавливает выполнение потока и сообщает о потерянных вызовах пробуждения.

Проблема заключается в том, что на более высоких частотах система начинает терять предельные сроки, хотя использование ЦП ниже 10%. Я думаю, это связано с тем, что планировщик не просыпал поток достаточно часто, чтобы проверить блокирующий вызов. Есть ли команда, которую я могу использовать, чтобы сообщить планировщику разбудить поток через определенные промежутки времени, насколько это возможно? Занято-ожидание - плохой вариант, поскольку система обрабатывает многие другие задачи.

Спасибо.

Ответ 1

Вам нужно получить RT linux *, а затем увеличить приоритет RT процесса, который вы хотите проснуться с регулярными интервалами.

Кроме того, я не вижу проблем в вашем коде, и если ваш процесс не блокируется, он должен работать нормально.

(*) RT linux - os с некоторыми исправлениями в реальном времени.

Ответ 2

Один из способов уменьшить задержку планировщика - запустить ваш процесс с использованием планировщика реального времени, такого как SCHED_FIFO. См. sched_setscheduler.

Как правило, это значительно улучшает латентность, но, тем не менее, это не гарантирует, что для дальнейшего снижения латентных всплесков вам нужно будет перейти в реальном времени в Linux или в операционную систему, такую ​​как VxWorks, RTEMS или QNX.

Ответ 3

Вы не сможете делать то, что хотите, если не запускаете его в реальной "ОС реального времени".

Ответ 4

Если это только Linux для системы x86, я бы выбрал таймер HPET. Я думаю, что все современные ПК имеют встроенный таймер, и он очень и очень точный. Я разрешаю вам определять обратный вызов, который будет вызываться каждые миллисекунды, и в этом обратном вызове вы можете выполнять свои вычисления (если они просты) или просто запускать работу другого потока с использованием некоторого объекта синхронизации (например, условная переменная) Вот пример использования этого таймера http://blog.fpmurphy.com/2009/07/linux-hpet-support.html

Ответ 5

Наряду с другими советами, такими как установка класса планирования SCHED_FIFO, вам нужно будет использовать ядро ​​Linux, скомпилированное с достаточно высокой скоростью тика, чтобы оно соответствовало вашему сроку.

Например, ядро, скомпилированное с CONFIG_HZ из 100 или 250 Гц (прерывания таймера в секунду), никогда не сможет быстрее реагировать на события таймера.

Вы также должны настроить свой таймер на несколько быстрее, чем вам на самом деле, потому что таймерам разрешено выходить за пределы требуемого времени, но никогда не истекает раньше, это даст вам лучшие результаты. Если вам нужно 1 мс, тогда я бы рекомендовал попросить нас 999.