table of contents
- bookworm 4.18.1-1
- bookworm-backports 4.24.0-2~bpo12+1
- testing 4.24.0-2
- unstable 4.24.0-2
sched(7) | Miscellaneous Information Manual | sched(7) |
ИМЯ¶
sched - обзор планирования работы ЦП
ОПИСАНИЕ¶
Начиная с Linux 2.6.23 планировщиком по умолчанию является CFS — «полностью честный планировщик» (Completely Fair Scheduler). Планировщик CFS заменил использовавшийся ранее «O(1)».
Краткие сведения о программном интерфейсе¶
Для управления планированием, алгоритмом и приоритетом процессов (более точно, нитей) на ЦП в Linux имеются следующие системные вызовы:
- nice(2)
- Назначает новое значение уступчивости вызвавшей нити и возвращает новое значение уступчивости.
- getpriority(2)
- Возвращает значение уступчивости нити, группы процессов или набора нитей, принадлежащих указанному пользователю.
- setpriority(2)
- Изменяет значение уступчивости нити, группы процессов или набора нитей, принадлежащих указанному пользователю.
- sched_setscheduler(2)
- Назначает алгоритм планирования и параметры заданной нити.
- sched_getscheduler(2)
- Возвращает алгоритм планирования и параметры заданной нити.
- sched_setparam(2)
- Назначает параметры планирования заданной нити.
- sched_getparam(2)
- Возвращает параметры планирования заданной нити.
- sched_get_priority_max(2)
- Возвращает максимальный приоритет, доступный заданному алгоритму планирования.
- sched_get_priority_min(2)
- Возвращает минимальный приоритет, доступный заданному алгоритму планирования.
- sched_rr_get_interval(2)
- Возвращает квант, используемый нитями, которые запланированы «циклическим» (round-robin) алгоритмом планирования.
- sched_yield(2)
- Заставляет вызывающего освободить ЦП для выполнения других нитей.
- sched_setaffinity(2)
- (только в Linux) Назначить увязываемый ЦП указанной нити.
- sched_getaffinity(2)
- (только в Linux) Возвращает увязываемый ЦП указанной нити.
- sched_setattr(2)
- Назначает алгоритм планирования и параметры заданной нити. Данный системный вызов (есть только в Linux) предоставляет охватывающий набор возможностей sched_setscheduler(2) и sched_setparam(2).
- sched_getattr(2)
- Возвращает алгоритм планирования и параметры заданной нити. Данный системный вызов (есть только в Linux) предоставляет охватывающий набор возможностей sched_setscheduler(2) и sched_setparam(2).
Алгоритмы планирования¶
Планировщик — это часть ядра, которая решает какая запущенная нить будет выполняться процессором следующей. Каждой нити назначается алгоритм планирования и статический приоритет планирования, sched_priority. Планировщик принимает решение на основе данных об алгоритме планирования и статическом приоритете всех нитей системы.
Для нитей, которые планируются одним из обычных алгоритмом планирования (SCHED_OTHER, SCHED_IDLE, SCHED_BATCH), значение sched_priority при принятии решения не используется (должен быть указан 0).
Для процессов, которые планируются одним из алгоритмов реального времени (SCHED_FIFO, SCHED_RR), значение приоритета sched_priority лежит в диапазоне от 1 (низкий) до 99 (высокий) Как и числовые значения, нити реального времени всегда имеют более высокий приоритет чем обычные нити. Но заметим: согласно POSIX.1 от реализации для алгоритмов реального времени требуется поддержка только 32 различных уровней приоритета, и в некоторых системах обеспечивается только этот минимум. В переносимых программах нужно использовать вызовы sched_get_priority_min(2) и sched_get_priority_max(2) для для определения диапазона приоритетов, поддерживаемых определённым алгоритмом.
По существу, планировщик хранит в памяти списки всех работающих нитей для каждого возможного значения sched_priority. Чтобы определить какую нить выполнять следующей, планировщик ищет непустой список с самым высоким статическим приоритетом и выбирает нить из начала списка.
Алгоритм планирования определяет, в какое место списка будет добавлена нить с тем же статическим приоритетом и как она будет перемещаться внутри этого списка.
Всё планирование основано на вытеснении: если нить с высшим статическим приоритетом готова к выполнению, текущая выполняющаяся нить будет вытеснена и возвращена в список ожидания согласно своему уровню статического приоритета. Алгоритм выполнения определяет порядок только внутри списка готовых к выполнению нитей с одинаковым статическим приоритетом.
SCHED_FIFO: планировщик «первым вошёл — первым выше뻶
SCHED_FIFO can be used only with static priorities higher than 0, which means that when a SCHED_FIFO thread becomes runnable, it will always immediately preempt any currently running SCHED_OTHER, SCHED_BATCH, or SCHED_IDLE thread. SCHED_FIFO is a simple scheduling algorithm without time slicing. For threads scheduled under the SCHED_FIFO policy, the following rules apply:
- •
- Нить, выполняемая с алгоритмом SCHED_FIFO и вытесненная другой нитью с большим приоритетом, останется в начале списка нитей с приоритетом как у неё, и её исполнение будет продолжено сразу после того, как закончатся нити с большими приоритетами.
- •
- Когда заблокированная нить с алгоритмом SCHED_FIFO готова к работе, она помещается в конец списка нитей с приоритетом как у неё.
- •
- Если вызовом sched_setscheduler(2), sched_setparam(2), sched_setattr(2), pthread_setschedparam(3) или pthread_setschedprio(3) изменяется приоритет выполняющейся или готовой к выполнению нити SCHED_FIFO, задаваемой pid, то результат положения нити в списке зависит от направления изменения приоритета нити:
- (а)
- Если приоритет нити повышается, то она помещается в конец списка со своим новым приоритетом. В результате, может быть вытеснена выполняемая в этот момент нить с таким же приоритетом.
- (б)
- Если приоритет нити не изменяется, то её положение в списке выполнения не изменяется.
- (в)
- Если приоритет нити понижается, то она помещается в начало списка со своим новым приоритетом.
- Согласно POSIX.1-2008 изменение приоритета нити (или алгоритма) с помощью какого-либо механизма отличного от pthread_setschedprio(3), должно приводить к размещению нити в конец списка с её приоритетом.
- •
- Нить, вызывающая sched_yield(2), будет помещена в конец списка.
Других событий для перемещения нити с алгоритмом SCHED_FIFO в списке ожидания запускаемых нитей с одинаковым статическим приоритетом не существует.
Нить с алгоритмом SCHED_FIFO выполняется до тех пор, пока не будет заблокирована запросом ввода/вывода, вытеснена нитью с большим приоритетом или пока не вызовет sched_yield(2).
SCHED_RR: планирование выполнения по циклу¶
SCHED_RR — это просто улучшение SCHED_FIFO. Всё, относящееся к SCHED_FIFO, справедливо и для SCHED_RR за исключением того, что каждой нити разрешено работать непрерывно не дольше максимального кванта времени. Если нить с алгоритмом SCHED_RR работала столько же или дольше, чем квант, то она помещается в конец списка с тем же приоритетом. Нить с алгоритмом SCHED_RR, вытесненная нитью с большим приоритетом, возобновляя работу, использует остаток своего кванта из старого цикла. Длину этого кванта можно узнать, вызвав sched_rr_get_interval(2).
SCHED_DEADLINE: Модель планирования случайной задачи с предельным сроком¶
Since Linux 3.14, Linux provides a deadline scheduling policy (SCHED_DEADLINE). This policy is currently implemented using GEDF (Global Earliest Deadline First) in conjunction with CBS (Constant Bandwidth Server). To set and fetch this policy and associated attributes, one must use the Linux-specific sched_setattr(2) and sched_getattr(2) system calls.
Случайная задача — одна из последовательности заданий (jobs), где каждое задание активизируется не более чем один раз за промежуток времени. Также у каждого задания есть относительный крайний срок, до которого оно должно завершить выполнение и время вычисления — время ЦП, необходимое для выполнения задания. Момент, когда задача пробуждается из-за выполнения нового задания, называется временем принятия (arrival time) (его ещё называют временем запроса (request time) или временем выпуска (release time). Время начала — это время когда задача начинает выполнение. Абсолютный предельный срок получается сложением относительного предельного срока с временем принятия.
Эти определения показаны в следующей диаграмме:
принятие/пробуждение абсолютный предельный срок
| время начала |
| | |
v v v -----x--------xooooooooooooooooo--------x--------x---
|<- comp. time ->|
|<------- относительный предельный срок ------>|
|<-------------- промежуток времени ------------------->|
При назначении нити алгоритма SCHED_DEADLINE с помощью sched_setattr(2) можно указать три параметра: Runtime, Deadline и Period. Эти параметры не обязательно соответствуют вышеупомянутым терминам: на практике, Runtime задаётся чуть больше чем среднее время вычисления (или время вычисления в самом плохом варианте для задач жёсткого реального времени), Deadline равен относительному предельному сроку, а Period равен промежутку времени. Таким образом, при планировании SCHED_DEADLINE мы имеем:
принятие/пробуждение абсолютный предельный срок
| время начала |
| | |
v v v -----x--------xooooooooooooooooo--------x--------x---
|<-- Runtime ------->|
|<----------- Deadline ----------->|
|<-------------- Period ------------------->|
Три параметра алгоритма с крайним сроком соответствуют полям sched_runtime, sched_deadline и sched_period структуры sched_attr; смотрите sched_setattr(2). Значения этих полей задаются в наносекундах. Если sched_period равно 0, то его значение равно sched_deadline.
Для ядра требуется соблюдение условия:
sched_runtime <= sched_deadline <= sched_period
In addition, under the current implementation, all of the parameter values must be at least 1024 (i.e., just over one microsecond, which is the resolution of the implementation), and less than 2^63. If any of these checks fails, sched_setattr(2) fails with the error EINVAL.
CBS гарантирует отсутствие влияния задача друг на друга, регулируя (throttling) нити, которые пытаются превысить заданное им время выполнения (Runtime).
Чтобы гарантировать выполнение алгоритма планирования крайнего срока, ядро должно предотвращать ситуации, где установка SCHED_DEADLINE нитям не выполнима (не может быть запланирована) для указанных ограничений. Для этого ядро выполняет тест допустимости при назначении или изменении алгоритма SCHED_DEADLINE и атрибутов. В данном тесте вычисляется, выполнимы ли изменения; если нет, то sched_setattr(2) завершается с ошибкой EBUSY.
Например, для этого требуется (но не обязательно достаточно), чтобы общая загруженность была меньше или равной общему количеству доступных ЦП, так как каждая нить максимально может работать весь промежуток времени, то есть загруженность нити равна её Runtime, поделённый на Period.
Чтобы удовлетворить гарантиям, которые даются, когда нити назначен алгоритм SCHED_DEADLINE, нити с SCHED_DEADLINE имеют наивысший приоритет (управляется пользователем) по сравнению с другими нитями в системе; если нить с SCHED_DEADLINE запускается, то она вытеснит любую нить, запланированную любым другим алгоритмом.
Вызов fork(2) в нити, запланированной SCHED_DEADLINE завершается ошибкой EAGAIN, если у нити не установлен флаг reset-on-fork (смотрите далее).
Нить с SCHED_DEADLINE, вызывающая sched_yield(2) приостановит текущее задание и будет ждать начала нового промежутка времени.
SCHED_OTHER: планирование с разделение времени (по умолчанию в Linux)¶
SCHED_OTHER можно использовать только с статическим приоритетом 0 (то есть, нити, работающие по алгоритму реального времени, всегда имеют приоритет над процессами с SCHED_OTHER). SCHED_OTHER — это стандартный планировщик Linux с разделением времени, предназначенный для всех нитей, не требующих специальных механизмов реального времени.
Для выполнения выбирается нить из списка со статическим приоритетом 0 на основе динамического приоритета, существующего только внутри этого списка. Динамический приоритет основан на значении уступчивости (смотрите ниже) и увеличивается с каждым квантом времени, при котором нить была готова к работе, но ей было отказано в этом планировщиком. Таким образом время равномерно распределяется между всеми нитями с алгоритмом SCHED_OTHER.
В дереве исходного кода ядра Linux алгоритм SCHED_OTHER на самом деле называется SCHED_NORMAL.
Значение уступчивости¶
Значение уступчивости — это атрибут, который можно использовать для влияния на планировщик ЦП с целью сделать процесс более популярным (или наоборот) при принятии решений о планировании выполнения. Он учитывается при планировании процессов с SCHED_OTHER и SCHED_BATCH (смотрите ниже). Значение уступчивости можно изменять с помощью nice(2), setpriority(2) или sched_setattr(2).
Согласно POSIX.1, значение уступчивости является атрибутом процесса; то есть нити процесса должны иметь одинаковое значение уступчивости. Однако в Linux значение уступчивости является атрибутом нити: разные нити одного процесса могут иметь разные значения уступчивости.
The range of the nice value varies across UNIX systems. On modern Linux, the range is -20 (high priority) to +19 (low priority). On some other systems, the range is -20..20. Very early Linux kernels (before Linux 2.0) had the range -infinity..15.
Степень влияния значения уступчивости на процессы с подобным SCHED_OTHER в разных системах UNIX различна и не одинакова даже между версиями ядра Linux.
With the advent of the CFS scheduler in Linux 2.6.23, Linux adopted an algorithm that causes relative differences in nice values to have a much stronger effect. In the current implementation, each unit of difference in the nice values of two processes results in a factor of 1.25 in the degree to which the scheduler favors the higher priority process. This causes very low nice values (+19) to truly provide little CPU to a process whenever there is any other higher priority load on the system, and makes high nice values (-20) deliver most of the CPU to applications that require it (e.g., some audio applications).
Для задания ограничения, до которого можно повышать значение уступчивости непривилегированному процессу, в используется Linux ограничение ресурса RLIMIT_NICE; смотрите setrlimit(2).
Дополнительную информацию о значении уступчивости смотрите подразделы свойств автогруппировки и группового планирования ниже.
SCHED_BATCH: планирование для пакетных процессов¶
(начиная с Linux 2.6.16) SCHED_BATCH можно использовать только с статическим приоритетом равным нулю. Этот алгоритм похож на SCHED_OTHER в том, что он планирует выполнение нити на основе её динамического приоритета (на основе значения nice). Различие в том, что в этом алгоритме планировщик всегда предполагает, что нить, в основном, использует ЦП. Следовательно, планировщик немного понизит вероятность её следующего пробуждения для того, чтобы эта нить уступила другим при планировании.
Этот алгоритм полезен при нагрузках не интерактивными задачами, но когда нежелательно понижать их значение nice и для задач, которым требуется предсказуемый алгоритм планирования без интерактивности, который приводит к дополнительным вытеснениям (между задачами нагрузки).
SCHED_IDLE: планирование заданий с очень низким приоритетом¶
(начиная с Linux 2.6.23) SCHED_IDLE можно использовать только с статическим приоритетом равным нулю; значение nice не учитывает в этом алгоритме.
Данный алгоритм предназначен для выполнения заданий с чрезвычайно низким приоритетом (даже ниже чем значение nice +19 в алгоритме SCHED_OTHER или SCHED_BATCH).
Сброс алгоритма планирования у дочерних процессов¶
В каждой нити есть флаг планирования reset-on-fork. Когда этот флаг установлен, потомки, создаваемые fork(2), не наследуют привилегированные алгоритмы планирования. Флаг reset-on-fork может быть задан так:
- •
- Логическим сложением флага SCHED_RESET_ON_FORK с аргументом policy при вызове sched_setscheduler(2) (начиная с Linux 2.6.32); или
- •
- заданием флага SCHED_FLAG_RESET_ON_FORK в attr.sched_flags при вызове sched_setattr(2).
Заметим, что константы, используемые в этих двух вызовам имеют разные имена. Состояние флага reset-on-fork может быть получено аналогичным образом с помощью sched_getscheduler(2) и sched_getattr(2).
Возможность reset-on-fork предназначена для приложений, проигрывающих медиа-файлы, и может использоваться для обхождения ограничения ресурса RLIMIT_RTTIME (см. getrlimit(2)), посредством создания нескольких дочерних процессов.
Точнее говоря, если указан флаг reset-on-fork, то к новым потомкам применяются следующие правила:
- •
- Если вызывающая нить имеет алгоритм планирования SCHED_FIFO или SCHED_RR, то у потомков алгоритм сбрасывается в SCHED_OTHER.
- •
- Если у вызывающего процесса значение nice отрицательно, то у потомков значение nice сбрасывается в ноль.
После установки флага reset-on-fork его можно сбросить только, если нить имеет мандат CAP_SYS_NICE. Этот флаг выключается у потомков, созданных через fork(2).
Привилегии и ограничения по ресурсам¶
Before Linux 2.6.12, only privileged (CAP_SYS_NICE) threads can set a nonzero static priority (i.e., set a real-time scheduling policy). The only change that an unprivileged thread can make is to set the SCHED_OTHER policy, and this can be done only if the effective user ID of the caller matches the real or effective user ID of the target thread (i.e., the thread specified by pid) whose policy is being changed.
Для задания или изменения SCHED_DEADLINE нить должна быть привилегированной (CAP_SYS_NICE).
Начиная с Linux 2.6.12, ограничитель ресурса RLIMIT_RTPRIO определяет максимум статического приоритета непривилегированной нити для алгоритмов SCHED_RR и SCHED_FIFO. Правила для изменения алгоритма планирования и приоритета:
- •
- Если непривилегированная нить имеет ненулевое значение мягкого ограничения RLIMIT_RTPRIO, то она может изменять свой алгоритм планирования и приоритет, но при этом значение приоритета не может быть больше чем максимальное значение её текущего приоритета и его мягкого ограничения RLIMIT_RTPRIO.
- •
- Если мягкое ограничение RLIMIT_RTPRIO равно 0, то разрешается только снижать приоритет или переключиться на алгоритм выполнения не реального времени.
- •
- Согласно тем же самым правилам другая непривилегированная нить может также сделать эти изменения, пока эффективный идентификатор пользователя нити, производящей изменение, совпадает с реальным или эффективным идентификатором пользователя изменяемой нити.
- •
- Special rules apply for the SCHED_IDLE policy. Before Linux 2.6.39, an unprivileged thread operating under this policy cannot change its policy, regardless of the value of its RLIMIT_RTPRIO resource limit. Since Linux 2.6.39, an unprivileged thread can switch to either the SCHED_BATCH or the SCHED_OTHER policy so long as its nice value falls within the range permitted by its RLIMIT_NICE resource limit (see getrlimit(2)).
Для привилегированных (CAP_SYS_NICE) нитей ограничение RLIMIT_RTPRIO игнорируется; как в старых ядрах, они могут произвольно менять алгоритм планирования и приоритет. Подробней смотрите в getrlimit(2) про RLIMIT_RTPRIO.
Ограничение использование ЦП процессами реального времени и процессами с крайним сроком¶
A nonblocking infinite loop in a thread scheduled under the SCHED_FIFO, SCHED_RR, or SCHED_DEADLINE policy can potentially block all other threads from accessing the CPU forever. Before Linux 2.6.25, the only way of preventing a runaway real-time process from freezing the system was to run (at the console) a shell scheduled under a higher static priority than the tested application. This allows an emergency kill of tested real-time applications that do not block or terminate as expected.
Начиная с Linux 2.6.25, есть другие способы работы с процессами реального времени и процессами с крайним сроком. Один из них — использовать ограничитель ресурса RLIMIT_RTTIME, задав потолок времени ЦП, которое процесс реального времени может задействовать. Подробней смотрите в getrlimit(2).
Since Linux 2.6.25, Linux also provides two /proc files that can be used to reserve a certain amount of CPU time to be used by non-real-time processes. Reserving CPU time in this fashion allows some CPU time to be allocated to (say) a root shell that can be used to kill a runaway process. Both of these files specify time values in microseconds:
- /proc/sys/kernel/sched_rt_period_us
- В данном файле задаётся планируемый промежуток времени, который равен 100% полосы ЦП. Значение в этом файле может лежать в диапазоне от 1 до INT_MAX, что даёт рабочий диапазон от 1 микросекунды до, приблизительно, 35 минут. Значение в файле по умолчанию равно 1000000 (1 секунда).
- /proc/sys/kernel/sched_rt_runtime_us
- The value in this file specifies how much of the "period" time can be used by all real-time and deadline scheduled processes on the system. The value in this file can range from -1 to INT_MAX-1. Specifying -1 makes the run time the same as the period; that is, no CPU time is set aside for non-real-time processes (which was the behavior before Linux 2.6.25). The default value in this file is 950,000 (0.95 seconds), meaning that 5% of the CPU time is reserved for processes that don't run under a real-time or deadline scheduling policy.
Время ответа¶
Блокированная нить с высоким приоритетом, ожидающая ввода/вывода, освобождает достаточно много процессорного времени до того, как снова начнёт работать. Авторы драйверов устройств могут более эффективно использовать это время, если воспользуются «медленным» обработчиком прерываний.
Разное¶
Дочерние процессы наследуют алгоритм планирования и его параметры после fork(2). Алгоритм планирования и параметры сохраняются при вызове execve(2).
Обычно, процессам реального времени необходимо блокировать память для того, чтобы избежать задержек при страничном обмене. Это можно сделать при помощи вызова mlock(2) или mlockall(2).
Свойство автогруппировки¶
Начиная с Linux 2.6.38 в ядре появилось свойство, называемое автогруппировкой; оно улучшает интерактивность рабочего окружения несмотря на многопроцессную интенсивную нагрузку ЦП, такую как сборка ядра Linux большим количеством параллельно собирающих процессов (т. е., командой make(1) с флагом -j).
Данное свойств работает совместно с планировщиком CFS, и ядро должно быть собрано с параметром CONFIG_SCHED_AUTOGROUP. В работающей системе свойство можно включать и выключать через файл /proc/sys/kernel/sched_autogroup_enabled; значение 0 выключает свойство, а 1 — включает. Значение по умолчанию равно 1, если ядро не загружалось с параметром noautogroup.
Новая автогруппа создаётся при создании нового сеанса с помощью setsid(2); например, это происходит при запуске нового окна терминала. Новый процесс, созданный fork(2), наследует членство в автогруппе родителя. Таким образом, все процессы в сеансе являются членами одной автогруппы. Автогруппа автоматически уничтожается при завершении последнего процесса в группе.
При включенной автогруппировке все члены автогруппы помещаются в в одну «группу задач» планировщика ядра. Планировщик CFS использует алгоритм, который уравнивает раздачу циклов ЦП между задачами группы. Преимущество такого подхода заключается в улучшении интерактивности рабочего стола, которую можно описать следующим примером.
Suppose that there are two autogroups competing for the same CPU (i.e., presume either a single CPU system or the use of taskset(1) to confine all the processes to the same CPU on an SMP system). The first group contains ten CPU-bound processes from a kernel build started with make -j10. The other contains a single CPU-bound process: a video player. The effect of autogrouping is that the two groups will each receive half of the CPU cycles. That is, the video player will receive 50% of the CPU cycles, rather than just 9% of the cycles, which would likely lead to degraded video playback. The situation on an SMP system is more complex, but the general effect is the same: the scheduler distributes CPU cycles across task groups such that an autogroup that contains a large number of CPU-bound processes does not end up hogging CPU cycles at the expense of the other jobs on the system.
A process's autogroup (task group) membership can be viewed via the file /proc/pid/autogroup:
$ cat /proc/1/autogroup /autogroup-1 nice 0
Также этот файл можно использовать для изменения полосы пропускания ЦП, выделенной автогруппе. Для этого в файл записывается диапазон «уступчивости», задающий значение уступчивости автогруппы. Допускаемый диапазон: от +19 (низкий приоритет) до -20 (высокий приоритет) (запись через write(2) значений вне это диапазона приводит к ошибке EINVAL).
Значение уступчивости автогруппы означает тоже самое что и значение уступчивости процесса, но распространяется на циклы ЦП автогруппы в целом, основываясь на относительных значениях уступчивости других автогрупп. Для процесса внутри автогруппы количество циклов ЦП, которые он получит, равно произведению значения уступчивости автогруппы (по сравнению с другими автогруппами) и значению уступчивости процесса (по сравнению с другими процессам в той же автогруппе).
Использование контроллера ЦП cgroups(7) для размещения процессов в cgroup не равную корневой cgroup ЦП, отменяет эффект автогруппировки.
Свойство автогруппировки группирует только процессы, планируемые алгоритмами не реального времени (SCHED_OTHER, SCHED_BATCH и SCHED_IDLE). Оно не группирует процессы, планируемые алгоритмами реального времени и с предельным сроком (deadline). Такие процессы планируются согласно правилам, описанным ранее.
Значение уступчивости и групповое планирование¶
При планировании процессов не реального времени (т. е., планируемых по алгоритмам SCHED_OTHER, SCHED_BATCH и SCHED_IDLE), планировщик CFS использует технику называемую «групповое планирование», если ядро было собрано с параметром CONFIG_FAIR_GROUP_SCHED (обычно так и есть).
При групповом планировании нити планируются по «группам задач». Группы задач имеют иерархические связи, берущие начало от начальной группы задач системы, называемой «корневая группа задач». Группы задач формируются согласно следующему:
- •
- Все нити в cgroup ЦП образуют группу задач. Родитель этой группы задач является группой задач соответствующей родительской cgroup.
- •
- Если автогруппировка разрешена, то все нити, помещённые (неявно) в автогруппу (т. е., одного сеанса, созданного setsid(2)), образуют группу задач. Таким образом, каждая новая автогруппа является отдельной группой задач. Корневая группа задач является родителем всех этих автогрупп.
- •
- Если автогруппировка разрешена, то корневая группа задач состоит из всех процессов в корневой cgroup ЦП, которые не были неявно помещены в новую автогруппу.
- •
- Если автогруппировка запрещена, то корневая группа задач состоит из всех процессов в корневой cgroup ЦП.
- •
- Если групповое планирование было запрещено (т. е., ядро собрано без параметра CONFIG_FAIR_GROUP_SCHED), то все процессы системы условно помещаются в одну группу задач.
При групповом планировании значение уступчивости нити влияет на решение о планировании только относительно других нитей в той же группе задач. Это слегка удивляет с точки зрения обычной семантики значения уступчивости в системах UNIX. В частности, если автогруппировка разрешена (по умолчанию во многих дистрибутивах), то применение к процессу setpriority(2) или nice(1) подействует только на планирование относительно других процессов, выполняющихся в том же сеансе (обычно, в том же окне терминала).
И наоборот, для двух процессов, которые (например) являются единственными привязанными к ЦП процессами в в разных сеансах (например, различные окна терминалов, в каждом задачи составляют разные автогруппы), изменение значения уступчивости процесса в одном из сеансов не повлияет на принятие решения планировщиком относительно процесса в другом сеансе. Возможно, здесь полезным обходным решением будет использовать команду, изменяющую значение уступчивости автогруппы всех процессов в сеансе терминала:
$ echo 10 > /proc/self/autogroup
Возможности выполнения в реальном времени из оригинальной версии Linux¶
Since Linux 2.6.18, Linux is gradually becoming equipped with real-time capabilities, most of which are derived from the former realtime-preempt patch set. Until the patches have been completely merged into the mainline kernel, they must be installed to achieve the best real-time performance. These patches are named:
patch-версия_ядра-rtверсия_заплатки
и могут быть скачаны с http://www.kernel.org/pub/linux/kernel/projects/rt/.
Без заплаток и до их полного включения в оригинальное ядро, через параметры ядра предлагается только три класса вытеснения: CONFIG_PREEMPT_NONE, CONFIG_PREEMPT_VOLUNTARY и CONFIG_PREEMPT_DESKTOP, которые, соответственно, не сокращают, частично сокращают и значительно сокращают задержку планирования при наихудшем случае.
С заплатками и после их полного включения в оригинальное ядро, в параметрах ядра появится новый пункт CONFIG_PREEMPT_RT. Если он будет выбран, то Linux преобразуется в обычную операционную систему реального времени. После этого для выполнения нити с настоящим приоритетом реального времени и минимальной задержкой планирования в наихудшем случае используются алгоритмы планирования FIFO и RR.
ПРИМЕЧАНИЯ¶
Для ограничения групп процессов потребления ЦП можно использовать контроллер ЦП cgroups(7).
Originally, Standard Linux was intended as a general-purpose operating system being able to handle background processes, interactive applications, and less demanding real-time applications (applications that need to usually meet timing deadlines). Although the Linux 2.6 allowed for kernel preemption and the newly introduced O(1) scheduler ensures that the time needed to schedule is fixed and deterministic irrespective of the number of active tasks, true real-time computing was not possible up to Linux 2.6.17.
СМОТРИТЕ ТАКЖЕ¶
chcpu(1), chrt(1), lscpu(1), ps(1), taskset(1), top(1), getpriority(2), mlock(2), mlockall(2), munlock(2), munlockall(2), nice(2), sched_get_priority_max(2), sched_get_priority_min(2), sched_getaffinity(2), sched_getparam(2), sched_getscheduler(2), sched_rr_get_interval(2), sched_setaffinity(2), sched_setparam(2), sched_setscheduler(2), sched_yield(2), setpriority(2), pthread_getaffinity_np(3), pthread_getschedparam(3), pthread_setaffinity_np(3), sched_getcpu(3), capabilities(7), cpuset(7)
Programming for the real world - POSIX.4 by Bill O. Gallmeister, O'Reilly & Associates, Inc., ISBN 1-56592-074-0.
The Linux kernel source files Documentation/scheduler/sched-deadline.txt, Documentation/scheduler/sched-rt-group.txt, Documentation/scheduler/sched-design-CFS.txt, and Documentation/scheduler/sched-nice-design.txt
ПЕРЕВОД¶
Русский перевод этой страницы руководства разработал(и) Alexander Golubev <fatzer2@gmail.com>, Azamat Hackimov <azamat.hackimov@gmail.com>, Hotellook, Nikita <zxcvbnm3230@mail.ru>, Spiros Georgaras <sng@hellug.gr>, Vladislav <ivladislavefimov@gmail.com>, Yuri Kozlov <yuray@komyakino.ru> и Иван Павлов <pavia00@gmail.com>
Этот перевод является свободной программной документацией; он распространяется на условиях общедоступной лицензии GNU (GNU General Public License - GPL, https://www.gnu.org/licenses/gpl-3.0.html версии 3 или более поздней) в отношении авторского права, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ.
Если вы обнаружите какие-либо ошибки в переводе этой страницы руководства, пожалуйста, сообщите об этом разработчику(ам) по его(их) адресу(ам) электронной почты или по адресу списка рассылки русских переводчиков.
10 февраля 2023 г. | Справочные страницы Linux 6.03 |