Я работаю над потоковым приложением на Linux в C++, который пытается быть реальным временем, делая действие с heartbeat, или максимально близко к нему.
На практике я нахожу, что ОС выгружает мой поток и вызывает задержки до одной десятой секунды, в то время как это выключается, заставляя heartbeat быть неправильным.
Существует ли способ, которым мой поток может подсказать ОС, которая теперь является хорошим временем к контекстному переключению он? Я мог выполнить этот вызов прямо после выполнения heartbeat и таким образом минимизировать задержку из-за плохого синхронизированного контекстного переключения.
Трудно сказать, в чем заключается основная проблема в вашем случае, но это определенно не то, что можно исправить с помощью вызова sched_yield ()
или pthread_yield ()
. Единственное четко определенное использование уступки в Linux - это позволить другому готовому потоку вытеснить текущий связанный с ЦП работающий поток с тем же приоритетом на том же ЦП в соответствии с политикой планирования SCHED_FIFO. Практически во всех случаях это плохое дизайнерское решение.
Если вы серьезно относитесь к своей цели «попытаться работать в реальном времени» в Linux, то, прежде всего, вам следует использовать параметр sched_setscheduler
в реальном времени (SCHED_FIFO или SCHED_RR, FIFO предпочтительно).
Во-вторых, получите полный патч вытеснения для Linux (с kernel.org , если ваш дистрибутив его не предоставляет. Он также даст вам возможность перепланировать потоки драйвера устройства и выполнить ваш поток выше, чем, скажем, потоки драйвера жесткого диска или Ethernet.
В-третьих, см. RTWiki и другие ресурсы для получения дополнительных советов о том, как разработать и настроить приложение реального времени.
Этого должно быть достаточно, чтобы получить время отклика менее 10 микро секунд, независимо от загрузки системы на любой достойной настольной системе. У меня есть встроенная система, в которой я выжимаю только 60 мкс отклика в режиме ожидания и 150 мкс при большой нагрузке на диск / систему, но она все равно на несколько порядков быстрее, чем то, что вы описываете.
Вы можете указать текущему выполняющемуся потоку приостановить выполнение с помощью различных команд, таких как yield .
Простое указание потоку сделать паузу не является детерманистическим, 999 раз оно может обеспечить хорошие интервалы, а 1 раз - нет.
Вы, вероятно, захотите взглянуть на планирование в реальном времени для получения согласованных результатов. Этот сайт http://www2.net.in.tum.de/~gregor/docs/pthread-scheduling.html кажется хорошей отправной точкой для исследования планирования потоков.
Меня немного смущает этот вопрос. Если ваша программа просто ожидает периодического контрольного сигнала, а затем выполняет некоторую работу, тогда ОС должна знать, чтобы запланировать другие действия, когда вы вернетесь к ожиданию этого контрольного сигнала.
Вы крутите флаг не для того, чтобы «сердцебиение», не так ли?
Я не слишком уверен в Linux, но в Windows было объяснено, что вы не можете попросить систему не прерывать вас по нескольким причинам (в основном первый параграф). Навскидку, одна из причин - аппаратные прерывания, которые могут произойти в любое время и над которыми у вас нет контроля.
EDIT Какой-то парень только что предложил использовать sched_yield
, а затем удалил свой ответ. Однако это освободит время для всего вашего процесса. Вы также можете использовать sched_setscheduler
для подсказки ядру о том, что вам нужно.
используйте sched_yield
А для меховых потоков есть pthread_yield
http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_yield.3.html
Вы используете функцию таймера, такую как setitimer ()
, верно? ПРАВИЛЬНО ???
Если нет, значит, вы все делаете неправильно.
Возможно, вам потребуется указать интервал таймера, который немного короче того, что вам действительно нужно. Если вы используете приоритет планировщика в реальном времени и таймер, ваш процесс почти всегда будет просыпаться вовремя.
Я бы сказал, всегда вовремя, но Linux еще не идеальная ОС реального времени.