SCHED_SETAFFINITY(2)

ИМЯ
sched_setaffinity, sched_getaffinity - устанавливает и получает процессорную маску увязывания для нити

ОБЗОР
#define _GNU_SOURCE             /* Смотрите feature_test_macros(7) */
#include <sched.h>

int sched_setaffinity(pid_t pid, size_t cpusetsize,
                      const cpu_set_t *mask);

int sched_getaffinity(pid_t pid, size_t cpusetsize,
                      cpu_set_t *mask);

ОПИСАНИЕ
Процессорной маской увязывания нити задаётся набор процессоров, на которых разрешено выполняться нити. В многопроцессорных системах задание процессорной маски увязывания можно использовать для получения большей производительности. Например, выделение специального процессора определённой нити (т.е., задание в процессорной маске увязывания для нити одного ЦП и исключение этого ЦП из процессорных масок увязывания для остальных нитей) обеспечивает максимальную скорость выполнения этой нити. Ограничение для нити одним ЦП также исключает сокращение производительности в следствие недостоверности данных кэша, которая возникает, когда нить прекращает выполнение на одном ЦП и затем продолжает выполнение на другом. Маска увязывания ЦП представляется в виде структуры cpu_set_t, «набором процессоров», на которую указывает mask. В CPU_SET(3) описаны макросы для изменения набора ЦП. Вызов sched_setaffinity() устанавливает маску увязывания ЦП mask для нити, чей ID указан в pid. Если значение pid равно нулю, то используется вызывающая нить. В аргументе cpusetsize задаётся количество данных (в байтах), на которые указывает mask. Обычно его значение указывается как sizeof(cpu_set_t). Если нить, указанная в pid, в данный момент не выполняется на одном из ЦП, заданном в mask, то эта нить переносится на один из процессоров, назначаемых mask. Вызов sched_getaffinity() записывает в структуру cpu_set_t, на которую указывает mask, значение маски увязывания ЦП для нити, чей ID указан в pid. В аргументе cpusetsize задаётся размер mask (в байтах). Если значение pid равно нулю, то возвращается маска вызывающей нити.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении sched_setaffinity() и sched_getaffinity() возвращают 0. В случае ошибки возвращается -1, а errno устанавливается в соответствующее значение.

ОШИБКИ

EFAULT
    Указан некорректный адрес памяти.

EINVAL
    В маске увязывания ЦП mask указаны процессоры, которых физически нет в системе, и которые разрешены нити согласно любым ограничениям, которые могут налагаться механизмом «cpuset», описанном в cpuset(7).

EINVAL
    (sched_getaffinity() и, в ядрах до 2.6.9, sched_setaffinity()) Значение cpusetsize меньше размера маски увязывания, используемой в ядре.

EPERM
    (sched_setaffinity()) Вызывающая нить не имеет достаточно прав. Вызывающему требуется иметь эффективный пользовательский ID равный реальному пользовательскому ID или эффективному пользовательскому ID нити, указанной в pid, или он должен обладать мандатом CAP_SYS_NICE.

ESRCH
    Нить с идентификатором pid не найдена.

ВЕРСИИ
Системные вызовы увязывания ЦП появились в ядре Linux версии 2.5.8. Обёрточные функции появились в glibc 2.3. Первоначально, в интерфейсе glibc присутствовал аргумент cpusetsize, имевший тип unsigned int. В glibc 2.3.3 аргумент cpusetsize был удалён, но появился вновь в glibc 2.3.4 с типом size_t.

СООТВЕТСТВИЕ СТАНДАРТАМ
Данные системные вызовы есть только в Linux.

ЗАМЕЧАНИЯ
После вызова sched_setaffinity() набор процессоров, на которых действительно будет выполняться нить, вычисляется пересечением набора из аргумента mask и набором процессоров, присутствующих в системе. В дальнейшем, система может ограничить набор процессоров нити, если задействован механизм «cpuset», описанный в cpuset(7). Эти ограничения на действительный набор процессоров, используемых для нити, без уведомления налагаются ядром. Есть несколько способов определения количества процессоров в системе: по содержимому /proc/cpuinfo; с помощью syconf(3) получить значение параметров _SC_NPROCESSORS_CONF и _SC_NPROCESSORS_ONLN ; посчитать количество подкаталогов cpu в /sys/devices/system/cpu/. В sched(7) приведено описание схемы планирования Linux.

Маска увязывания является атрибутом нити, которая может изменяться независимо для каждой нити в группе нитей. В аргументе pid можно передавать значение, возвращаемое вызовом gettid(2). При значении pid равным 0 будет установлен атрибут вызывающей нити, а при передаче значения, возвращаемого вызовом getpid(2), устанавливается атрибут главной нити группы нитей (при работе с программным интерфейсом POSIX используйте функцию pthread_setaffinity_np(3) вместо sched_setaffinity()). Потомок, создаваемый с помощью fork(2), наследует маску увязывания ЦП. Маска увязывания сохраняется при вызове execve(2).

  Отличия между библиотекой C и ABI ядра
В данной справочной странице описан интерфейс увязывания ЦП, используемый в glibc. Реальный интерфейс системных вызов чуть отличается: аргумент mask имеет тип unsigned long *, отражая факт того, что используемая реализация наборов ЦП представляет собой просто битовую маску. При успешном выполнении ядерный системный вызов sched_getaffinity() возвращает размер типа данных cpumask_t (в байтах), который используется в ядре для представления битовой маски процессоров.

СМОТРИТЕ ТАКЖЕ
lscpu(1), nproc(1), taskset(1), clone(2), getcpu(2), getpriority(2), gettid(2), nice(2), sched_get_priority_max(2), sched_get_priority_min(2), sched_getscheduler(2), sched_setscheduler(2), setpriority(2), CPU_SET(3), pthread_setaffinity_np(3), sched_getcpu(3), capabilities(7), cpuset(7), sched(7)