setpriority(2) получить/установить приоритет планирования

Other Alias

getpriority

ОБЗОР

#include <sys/time.h>
#include <sys/resource.h>

int getpriority(int which, id_t who);
int setpriority(int which, id_t who, int prio);

ОПИСАНИЕ

С помощью вызова getpriority() можно получить приоритет планирования (scheduling priority) процесса, группы процессов или пользователя, которые заданы в аргументах which и who, а с помощью вызова setpriority() назначить его.

Значением which может быть одно из: PRIO_PROCESS, PRIO_PGRP или PRIO_USER, а значение who рассматривается относительно which (идентификатор процесса, если PRIO_PROCESS; группы процесса, если PRIO_PGRP; идентификатор пользователя, если PRIO_USER). Нулевое значение who означает (соответственно) вызывающий процесс, группу вызывающего процесса или реальный идентификатор пользователя вызывающего процесса. Аргумент Prio — это значение в диапазоне от -20 до 19 (смотрите ЗАМЕЧАНИЯ ниже). По умолчанию приоритет равен 0; более низкие значения соответствуют большему приоритету, который выделяет задаче планировщик.

Вызов getpriority() возвращает наивысший приоритет (наименьшее числовое значение) из приоритетов всех указанных процессов. Вызов setpriority() устанавливает приоритеты всех указанных процессов в заданное значение. Только суперпользователь может устанавливать более низкие значения приоритета.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

Так как getpriority() в качестве результата может возвращать -1, то перед вызовом необходимо очищать значение внешней переменной errno, а затем проверять его снова после вызова, чтобы определить, является ли -1 ошибкой или результатом вызова. Вызов setpriority() возвращает 0, если не было ошибок или -1, если произошла ошибка.

ОШИБКИ

EINVAL
Значение which не равно PRIO_PROCESS, PRIO_PGRP или PRIO_USER.
ESRCH
Не найдено процессов, которые заданы значениями which и who.

В дополнение к вышеуказанным ошибкам, setpriority() может завершиться неудачно:

EACCES
Вызывающий пытается понизить приоритет процесса, но он не имеет на это прав (в Linux: не имеет мандата CAP_SYS_NICE). Начиная с Linux 2.6.12, эта ошибка возникает только, если вызывающий пытается задать приоритет процесса вне границ диапазона мягкого ограничения ресурса процесса назначения RLIMIT_NICE; подробности смотрите в getrlimit(2).
EPERM
Процесс был найден, но эффективному идентификатору пользователя этого процесса не соответствует заданный в вызове эффективный (или реальный) идентификатор вызывающего и у вызывающего нет прав (в Linux: не имеет мандата CAP_SYS_NICE). Смотрите ЗАМЕЧАНИЯ далее.

СООТВЕТСТВИЕ СТАНДАРТАМ

POSIX.1-2001, POSIX.1-2008, SVr4, 4.4BSD (эти интерфейсы впервые появились в 4.2BSD).

ЗАМЕЧАНИЯ

Потомок, созданный с помощью fork(2), наследует значение nice родителя. При вызове execve(2) значение nice сохраняется.

Величина, с которой относительное значение nice влияет на планирование процессов, в различных системах UNIX и версиях ядер Linux различна. Начиная с ядра 2.6.23, в Linux принят алгоритм, который учитывает относительную разницу между значениями nice, что оказывает большее влияние при изменении. Его работа приводит к тому, что при очень низких значениях nice (+19) процессу действительно выделяется совсем мало времени ЦП, в то время как при любом другом большем значении приоритета система загружается сильнее и при самом высоком значении nice (-20) приложениям отдаётся большая часть времени ЦП (например, некоторым программам работы со звуком).

Детали условия возникновения ошибки EPERM зависят от системы. Описание, приведённое выше, соответствует POSIX.1-2001, и, кажется, ему удовлетворяют все System V-подобные системы. Ядра Linux до версии 2.6.12 требуют, чтобы эффективный идентификатор пользователя вызывающего совпадал с реальным идентификатором пользователя процесса who (вместо его эффективного идентификатора пользователя). В Linux 2.6.12 и новее требуется, чтобы эффективный идентификатор пользователя вызывающего совпадал с реальным или эффективным идентификатором пользователя процесса who. Все системы BSD (SunOS 4.1.3, Ultrix 4.2, 4.3BSD, FreeBSD 4.3, OpenBSD-2.5, …) действуют также как Linux 2.6.12 и новее.

Фактический диапазон значений приоритета варьируется в зависимости от версий ядра. В Linux, начиная с версии 1.3.43, имеет диапазон значений -20..19. В некоторых системах используется диапазон значений nice от -20 до 20.

Включать <sys/time.h> в настоящее время не требуется, но это увеличивает переносимость (безусловно, в <sys/resource.h> определена структура rusage с полями типа struct timeval, которая определена в <sys/time.h>).

Отличия между библиотекой C и ядром

Внутри ядра значения nice на самом деле представлены как диапазон (так как отрицательными числами задаются коды ошибок) и эти значения возвращаются системными вызовами setpriority() и getpriority(). Обёрточные функции glibc для этих системных вызовов преобразуют значение между пользовательским и ядерным диапазонами по формуле unice = 20 - knice (таким образом, ядерный диапазон 40..1 соответствует диапазону -20..19, видимый в пользовательском пространстве).

ДЕФЕКТЫ

Согласно POSIX, значение nice — свойство процесса. Однако в текущей реализации Linux/NPTL нитей POSIX значение nice — атрибут нити: различные нити в одном процессе могут иметь разные значения nice. Переносимые приложения не должны полагаться на поведение Linux, которое может стать стандартом в будущем.