Может ли мой поток помочь ОС решить, когда ее следует переключать в контекст?
Я работаю над многопоточным приложением в Linux на C++, которое пытается работать в режиме реального времени, выполняет какое-то действие или как можно ближе к нему.
На практике я обнаружил, что операционная система выменяет мой поток и вызывает задержки до одной десятой секунды, пока он выключен, в результате чего пульс становится нерегулярным.
Есть ли способ, которым мой поток может намекнуть ОС, что сейчас хорошее время для контекстного переключения? Я мог бы сделать этот вызов сразу после сердцебиения и, таким образом, минимизировать задержку из-за некорректного переключения контекста.
6 ответов
Трудно сказать, что является главной проблемой в вашем случае, но это, безусловно, не то, что можно исправить с помощью вызова 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 кажется, является хорошей отправной точкой для изучения планирования потоков.
Использование sched_yield
And fur threads there is an pthread_yield
http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_yield.3.html
Я немного смущен этим вопросом. Если ваша программа просто ждет периодического сердцебиения и затем выполняет некоторую работу, то ОС должна знать, чтобы планировать другие действия, когда вы вернетесь к ожиданию сердцебиения.
Вы не крутитесь на флаге, чтобы получить свое "сердцебиение", не так ли?
Вы используете функцию таймера, такую как setitimer()
, право? ПРАВО???
Если нет, то вы все делаете неправильно.
Вам может потребоваться указать интервал таймера, который немного короче того, что вам действительно нужно. Если вы используете приоритет планировщика в реальном времени и таймер, ваш процесс почти всегда проснется вовремя.
Я бы сказал всегда вовремя, но Linux пока не идеальная ОС реального времени.
Я не слишком уверен в Linux, но в Windows было объяснено, что вы не можете попросить систему не прерывать вас по нескольким причинам (в основном первый абзац). У меня в голове одна из причин - аппаратные прерывания, которые могут произойти в любое время и которые вы не можете контролировать.
РЕДАКТИРОВАТЬ Какой-то парень просто предложил использовать sched_yield
затем удалил свой ответ. Тем не менее, это оставит время для всего процесса. Вы также можете использовать sched_setscheduler
намекнуть ядру о том, что вам нужно.