Может ли мой поток помочь ОС решить, когда ее следует переключать в контекст? - PullRequest
9 голосов
/ 27 мая 2010

Я работаю над многопоточным приложением в Linux на C ++, которое пытается работать в режиме реального времени, выполняет какое-то действие или как можно ближе к нему.

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

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

Ответы [ 6 ]

5 голосов
/ 27 мая 2010

Трудно сказать, в чем заключается основная проблема в вашем случае, но, скорее всего, это не то, что можно исправить с помощью вызова sched_yield() или pthread_yield(). Единственное четко определенное использование для выдачи в Linux - это позволить другому готовому потоку выгружать текущий текущий связанный с ЦП поток с тем же приоритетом на том же ЦПУ в соответствии с политикой планирования SCHED_FIFO. Что является плохим дизайнерским решением почти во всех случаях.

Если вы серьезно относитесь к своей цели «пытаться работать в режиме реального времени» в Linux, то, прежде всего, вам следует использовать настройку sched_setscheduler в реальном времени (SCHED_FIFO или SCHED_RR, предпочтительно FIFO). Во-вторых, получите полный пакет исправлений для Linux (с kernel.org , если ваш дистрибутив не предоставляет его. Он также даст вам возможность перепланировать потоки драйвера устройства и выполнить ваш поток выше, скажем, потоки жесткого диска или драйвера Ethernet. В-третьих, см. RTWiki и другие ресурсы для получения дополнительных советов о том, как разрабатывать и настраивать приложения реального времени.

Этого должно быть достаточно, чтобы получить время отклика менее 10 микро секунд, независимо от загрузки системы в любой приличной настольной системе. У меня есть встроенная система, в которой я выживаю только 60 с лишним ответов и 150 при высокой нагрузке на диск / систему, но она все равно на несколько порядков быстрее, чем вы описываете.

3 голосов
/ 27 мая 2010

Вы можете указать текущему исполняющему потоку приостановить выполнение с помощью различных команд, таких как yield .

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

Возможно, вы захотите посмотреть на планирование в реальном времени для получения последовательных результатов. Этот сайт http://www2.net.in.tum.de/~gregor/docs/pthread-scheduling.html, кажется, является хорошей отправной точкой для исследования планирования потоков.

1 голос
/ 01 июня 2010

Вы используете функцию таймера, такую ​​как setitimer(), верно? RIGHT ???

Если нет, то вы все делаете неправильно.

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

Я бы сказал, всегда вовремя, но Linux пока не идеальная ОС реального времени.

1 голос
/ 27 мая 2010

Я немного смущен этим вопросом. Если ваша программа просто ждет периодического сердцебиения и затем выполняет некоторую работу, то ОС должна знать, чтобы планировать другие действия, когда вы вернетесь к ожиданию сердцебиения.

Вы не крутитесь на флаге, чтобы получить ваше "сердцебиение", не так ли?

1 голос
/ 27 мая 2010

Использование sched_yield

И меховые нитки есть pthread_yield http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_yield.3.html

0 голосов
/ 27 мая 2010

Я не слишком уверен в Linux, но в Windows было объяснено, что вы не можете попросить систему не прервать вас по нескольким причинам (в основном первый параграф) , У меня в голове одна из причин - аппаратные прерывания, которые могут произойти в любое время и которые вы не можете контролировать.

РЕДАКТИРОВАТЬ Какой-то парень просто предложил использовать sched_yield, а затем удалил свой ответ. Тем не менее, это оставит время для всего процесса. Вы также можете использовать sched_setscheduler, чтобы намекнуть ядру о том, что вам нужно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...