# ./sched_view 2006
2006: OTHER 0
# ./sched_set f 25 2006
# ./sched_view 2006
2006: FIFO 25
Листинг 35.3. Получение сведений о политике планирования и приоритете
procpri/sched_view.c
#include
#include "tlpi_hdr.h"
int
main(int argc, char *argv[])
{
int j, pol;
struct sched_param sp;
for (j = 1; j < argc; j++) {
pol = sched_getscheduler(getLong(argv[j], 0, "pid"));
if (pol == –1)
errExit("sched_getscheduler");
if (sched_getparam(getLong(argv[j], 0, "pid"), &sp) == –1)
errExit("sched_getparam");
printf("%s: %-5s", argv[j],
(pol == SCHED_OTHER)? "OTHER":
(pol == SCHED_RR)? "RR":
(pol == SCHED_FIFO)? "FIFO":
#ifdef SCHED_BATCH /* Относится только к Linux */
(pol == SCHED_BATCH)? "BATCH":
#endif
#ifdef SCHED_IDLE /* Относится только к Linux */
(pol == SCHED_IDLE)? "IDLE":
#endif
"???");
printf("%2d\n", sp.sched_priority);
}
exit(EXIT_SUCCESS);
}
procpri/sched_view.c
Предотвращение блокирования системы процессами реального времени
Поскольку процессы SCHED_RR и SCHED_FIFO опережают любую низкоприоритетную программу (например, командную оболочку, в которой эти процессы запущены), при разработке приложений, использующих эти политики, необходимо учитывать возможность того, что слишком активный процесс, работающий в режиме реального времени, может занять все ресурсы ЦПУ и заблокировать систему. Существует несколько программных способов этого избежать.
• Задействуя вызов setrlimit(), установить мягкое ограничение для процессорного времени (RLIMIT_CPU, описанный в разделе 36.3) на достаточно низком уровне. Если процесс потребляет слишком много ресурсов ЦПУ, ему будет послан сигнал SIGXCPU, который по умолчанию должен привести к его завершению.
• Установить таймер с помощью вызова alarm(). Если процесс продолжает работать на протяжении времени, которое превышает количество секунд, заданное в таймере, он будет завершен по сигналу SIGALRM.
• Создать сторожевой процесс, который работает с высоким приоритетом реального времени. Он может постоянно находиться в цикле, переходя в режим сна на определенное время, и затем проверяя состояние других процессов. Такой мониторинг может включать в себя измерение процессорного времени, потребляемого процессами (см. обсуждение функции clock_getcpuclockid() в подразделе 23.5.3), а также проверку их политики планирования и приоритета с помощью вызовов sched_getscheduler() и sched_getparam(). Если какой-то процесс ведет себя неправильно, сторожевой поток может понизить его приоритет или послать ему сигнал, который его остановит или завершит.
• Начиная с версии 2.6.25, ядро Linux предоставляет нестандартное ограничение на ресурсы, RLIMIT_RTTIME, позволяющее контролировать объем процессорного времени, которое может быть потреблено во время одного всплеска активности процесса, работающего в режиме реального времени. Ограничение RLIMIT_RTTIME указывается в микросекундах и ограничивает количество процессорного времени, которое процесс может потребить без выполнения блокирующих системных вызовов. При выполнении такого вызова насчитанное время сбрасывается к нулю. Однако этого не происходит, если процесс опережается другой, более приоритетной программой, если истекает временной отрезок, выделенный ему планировщиком (при использовании политики SCHED_RR), или в случае выполнения вызовов sched_yield() (см. подраздел 35.3.3). Когда процесс достигает установленного ограничения, то, как и в случае с ограничением RLIMIT_CPU, ему передается сигнал SIGXCPU, который по умолчанию приводит к его завершению.
Это нововведение, появившееся в ядре версии 2.6.25, также помогает предотвратить блокирование системы слишком активными процессами. Подробности ищите в исходном файле ядра Documentation/scheduler/sched-rt-group.txt.
Предотвращение наследования привилегированной политики планирования дочерними процессами
В Linux 2.6.32 было добавлено значение SCHED_RESET_ON_FORK, которое можно указать для аргумента policy при вызове sched_setscheduler(). Это флаг, который с помощью логического ИЛИ используется совместно с политиками, перечисленными в табл. 35.1. Если его установить, потомок, созданный процессом с помощью вызова fork(), не наследует его привилегированную политику планирования и приоритет. При этом действуют следующие правила.
• Если процесс имеет политику планирования реального времени (SCHED_RR или SCHED_FIFO), политика потомка сбрасывается к стандартному циклическому алгоритму разделения времени SCHED_OTHER.
• Если процесс имеет отрицательное (то есть высокое) значение nice, это значения для потомка сбрасывается к нулю.