Linux, нужна точная синхронизация программ. Программа пробуждения по расписанию - PullRequest
11 голосов
/ 10 июня 2011

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

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

 timerfd_create(CLOCK_MONOTONIC, 0)

, а затем передачи желаемого времени ожидания в структуре с помощью

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

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

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

Спасибо.

Ответы [ 5 ]

5 голосов
/ 10 июня 2011

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

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

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

2 голосов
/ 10 июня 2011

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

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

1 голос
/ 05 ноября 2011

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

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

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

1 голос
/ 10 июня 2011

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

1 голос
/ 10 июня 2011

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

...