Листинг 35.2. Изменение политики планирования и приоритета процессов
procpri/sched_set.c
#include
#include "tlpi_hdr.h"
int
main(int argc, char *argv[])
{
int j, pol;
struct sched_param sp;
if (argc < 3 || strchr("rfobi", argv[1][0]) == NULL)
usageErr("%s policy priority [pid…]\n"
" policy is 'r' (RR), 'f' (FIFO), "
#ifdef SCHED_BATCH /* Относится только к Linux */
"'b' (BATCH), "
#endif
#ifdef SCHED_IDLE /* Относится только к Linux */
"'i' (IDLE), "
#endif
"or 'o' (OTHER)\n",
argv[0]);
pol = (argv[1][0] == 'r')? SCHED_RR:
(argv[1][0] == 'f')? SCHED_FIFO:
#ifdef SCHED_BATCH
(argv[1][0] == 'b')? SCHED_BATCH:
#endif
#ifdef SCHED_IDLE
(argv[1][0] == 'i')? SCHED_IDLE:
#endif
SCHED_OTHER;
sp.sched_priority = getInt(argv[2], 0, "priority");
for (j = 3; j < argc; j++)
if (sched_setscheduler(getLong(argv[j], 0, "pid"), pol, &sp) == –1)
errExit("sched_setscheduler");
exit(EXIT_SUCCESS);
}
procpri/sched_set.c
Привилегии и ограничения на ресурсы, которые влияют на изменение параметров планирования
В ядрах версии ниже 2.6.12 менять политику планирования и приоритет обычно позволено только привилегированным процессам (CAP_SYS_NICE). Единственное исключение к этому требованию состоит в том, что непривилегированный процесс может изменять политику планирования на SCHED_OTHER, если его действующий пользовательский идентификатор совпадает с таковым у целевого процесса.
В версии ядра 2.6.12 появился новое, нестандартное ограничение ресурсов под названием RLIMIT_RTPRIO, которое изменило вышеописанные правила. Как и в старых ядрах, привилегированный (CAP_SYS_NICE) процесс может вносить любые изменения в политику и приоритет любой программы. Однако теперь то же самое может делать и обычный процесс. Для этого должны выполняться следующие условия.
• Если процесс имеет мягкое ненулевое ограничение RLIMIT_RTPRIO, он может вносить произвольные изменения в свою политику планирования и приоритет. При этом учитывая, что верхнее ограничение для приоритета реального времени является максимальным значением его текущего приоритета (если процесс в этот момент работает в рамках политики реального времени) и значением RLIMIT_RTPRIO.
• Если мягкое ограничение процесса RLIMIT_RTPRIO равно 0, все, что он может сделать, — понизить свой приоритет планирования или переключиться с политики реального времени на обычную.
• Политика SCHED_IDLE является особенной. Процесс, который работает под ее управлением, не может менять свою политику, каким бы ни было значение ограничения RLIMIT_RTPRIO.
• Изменения политики и приоритета можно также выполнять из другого непривилегированного процесса, если его действующий пользовательский идентификатор совпадает с реальным или действующим пользовательским идентификатором (именем пользователя) целевого процесса.
• Мягкое ограничение процесса RLIMIT_RTPRIO определяет только те изменения, которые он сам или другой привилегированный процесс может вносить в политику планирования и приоритет. Ненулевое ограничение не дает непривилегированному процессу право изменять политику планирования и приоритет других процессов.
Получение данных о политиках планирования и приоритетах
Системные вызовы sched_getscheduler() и sched_getparam() позволяют получить сведения о политике планирования и приоритете процесса.
#include
int sched_getscheduler(pid_t
Возвращает политику планирования или –1, если произошла ошибка
int sched_getparam(pid_t
Возвращает 0 при успешном завершении или –1, если произошла ошибка
В обоих этих системных вызовах аргумент pid обозначает идентификатор процесса, информацию о котором нужно получить. Если он равен 0, возвращаются данные о вызывающем процессе. Оба вызова могут быть использованы непривилегированными процессами для получения информации о любом другом процессе вне зависимости от привилегий.
Системный вызов sched_getparam() возвращает политику планирования реального времени в поле sched_priority внутри структуры sched_param, на которую указывает аргумент param.
В случае успешного выполнения sched_getscheduler() возвращает одну из политик, перечисленных ранее в табл. 35.1.
Программа, представленная в листинге 35.3, задействует вызовы sched_getscheduler() и sched_getparam() для получения сведений о политике и приоритете всех процессов, чьи идентификаторы переданы в качестве аргументов командной строки. Использование этой программы, а также программы из листинга 35.2, демонстрируется на примере следующей сессии командной оболочки:
$ su
Password:
# sleep 100 &
[1] 2006