Может ли мой поток помочь ОС решить, когда ее следует переключать в контекст?

Я работаю над многопоточным приложением в 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 намекнуть ядру о том, что вам нужно.

Другие вопросы по тегам