Планирование нитей
В библиотеке нитей предусмотрен набор функций для планирования нитей и управления планированием.
Кроме того, имеются функции для управления планированием нитей во время операций синхронизации, например, при установке взаимной блокировки. У каждой нити есть свой набор параметров планирования. Эти параметры можно установить с помощью объекта атрибутов нити еще до создания самой нити. Параметры можно динамически изменять во время обработки нити.
Управление планированием нитей часто представляет собой сложную задачу. Поскольку планировщик обрабатывает все нити в системе, параметры планирования конкретной нити взаимодействуют с параметрами планирования других нитей в этом и других процессах. Если вы хотите управлять планированием нитей, в первую очередь используйте перечисленные ниже средства.
- Настройка атрибутов планирования при создании нити
- Динамическое изменение атрибутов планирования уже созданной нити
- Определение влияния взаимной блокировки на планирование нитей при создании взаимной блокировки (планирование синхронизации).
- Динамическое изменение атрибутов планирования нити в ходе синхронизации (планирование синхронизации).
Параметры планирования
У нити есть следующие параметры планирования:
| Параметр | Описание |
|---|---|
| область действия | Область действия нити определяется моделью обработки нитей, используемой библиотекой. |
| стратегия | Стратегия планирования нити определяет, как планировщик работает с нитью после передачи ей управления. |
| приоритет | Приоритет планирования нити определяет относительную степень важности ее выполнения. |
Параметры планирования можно устанавливать как до создания нити, так и в ходе ее выполнения. Как правило, необходимо управлять параметрами планирования только для нитей, требующих много ресурсов процессора. Поэтому значения по умолчанию, устанавливаемые библиотекой нитей, приходится изменять достаточно редко.
Работа с атрибутом inheritsched
Атрибут inheritsched объекта атрибутов нити указывает способ определения атрибутов планирования нити. Возможны следующие значения:
| Значения | Описание |
|---|---|
| PTHREAD_INHERIT_SCHED | Означает, что новая нить наследует набор атрибутов планирования (атрибуты schedpolicy и schedparam) от породившей ее нити. Атрибуты планирования, указанные в объекте атрибутов, игнорируются. |
| PTHREAD_EXPLICIT_SCHED | Означает, что атрибуты планирования вновь созданной нити берутся из соответствующего объекта атрибутов. |
Значение атрибута inheritsched по умолчанию равно PTHREAD_INHERIT_SCHED. Значение атрибута изменяется с помощью функции pthread_attr_setinheritsched. Функция pthread_attr_getinheritsched возвращает текущее значение атрибута.
Для установки значений атрибутов планирования в объекте атрибутов нити следует сначала установить значение inheritsched равным PTHREAD_EXPLICIT_SCHED. В противном случае значения атрибутов планирования из объекта атрибутов будут проигнорированы.
Стратегия и приоритеты планирования
В библиотеке нитей реализованы следующие стратегии планирования:
| Библиотека | Описание |
|---|---|
| SCHED_FIFO | Планирование по принципу простой очереди "первый вошел, первый вышел" (FIFO). Каждой нити присваивается постоянный приоритет; если несколько нитей имеют один и тот же приоритет, они выполняются в порядке FIFO. |
| SCHED_RR | Планирование по принципу "карусели" (RR). Каждой нити присваивается постоянный приоритет; если несколько нитей имеют один и тот же приоритет, им в порядке FIFO выделяются равные значения времени процессора. |
| SCHED_OTHER | Способ планирования, принятый в AIX по умолчанию. Каждой нити присваивается приоритет, который планировщик может динамически изменять в соответствии с уровнем ее активности; каждой нити выделяется определенное число квантов времени. В других системах могут применяться другие стратегии планирования. |
До AIX версии 5.3 изменение приоритета нити при указании стратегии планирования SCHED_OTHER недопустимо. В этом случае ядро напрямую управляет приоритетом и функции pthread_setschedparam можно передать только значение DEFAULT_PRIO. Значение DEFAULT_PRIO определено в файле pthread.h в качестве 1. Прочие значения игнорируются.
Начиная с AIX 5.3, вы можете изменить приоритет нити при указании стратегии планирования SCHED_OTHER. Функции pthread_setschedparam можно передавать значение от 40 до 80, однако значения, превышающие 60, могут указывать только привилегированные пользователи. Приоритет в диапазоне от 1 до 39 соответствует приоритету 40, а приоритет от 81 до 127 - приоритету 80.
| Поля | Описание |
|---|---|
| sched_priority | Задает приоритет. |
| sched_policy | Это поле игнорируется библиотекой нитей. Не используйте его. |
Установка стратегии планирования и приоритета при создании нити
Для задания стратегии планирования при создании нити следует установить соответствующее значение атрибута schedpolicy в объекте атрибутов нити. С помощью функции pthread_attr_setschedpolicy можно присвоить атрибуту schedpolicy любое из определенных ранее значений. Текущее значение атрибута schedpolicy для данной нити можно узнать с помощью функции pthread_attr_getschedpolicy.
Для задания приоритета планирования при создании нити следует установить соответствующее значение атрибута schedparam в объекте атрибутов нити. Функция pthread_attr_setschedparam устанавливает значение атрибута schedparam, копируя его из указанной структуры. Функция pthread_attr_getschedparam возвращает текущее значение атрибута schedparam.
sched_param schedparam;
schedparam.sched_priority = 3;
pthread_attr_init(&attr);
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
pthread_attr_setschedpolicy(&attr, SCHED_RR);
pthread_attr_setschedparam(&attr, &schedparam);
pthread_create(&thread, &attr, &start_routine, &args);
pthread_attr_destroy(&attr);Атрибут inheritsched подробно описан в разделе Работа с атрибутом inheritsched.Установка атрибутов планирования во время выполнения
Функция pthread_getschedparam возвращает значения атрибутов нити schedpolicy и schedparam. Установить эти атрибуты можно с помощью функции pthread_setschedparam. При изменении стратегии и приоритета нити, которая в этот момент обрабатывается процессором, новые значения вступят в силу при следующей обработке нити. Если нить в данный момент не обрабатывается, она может быть запущена сразу после вызова функции установки атрибутов.
Допустим, например, для нити Т применяется стратегия планирования round-robin, и во время обработки этой нити значение ее атрибута schedpolicy изменяется на FIFO. Нить T будет выполняться до конца выделенного ей времени, после чего вступят в силу новые атрибуты планирования. Если нити с более высоким приоритетом отсутствуют, Т будет запущена еще раз, даже есть другие нити с тем же приоритетом, что и Т. Другой пример: пусть нить имеет низкий приоритет и в данный момент не обрабатывается. Если другая нить повысит ее приоритет с помощью функции pthread_setschedparam, то при отсутствии нитей с более высоким приоритетом исходная нить будет запущена сразу же.
Сведения о стратегии планирования
- При применении стратегии round-robin все нити с одинаковым приоритетом, независимо от уровня их активности, находятся в равном положении. Это может оказаться полезным при написании программ, в которых необходимо опрашивать датчики или периодически записывать информацию на внешние устройства.
- Стратегию FIFO следует применять с большой осторожностью. Нить, для которой применяется стратегия FIFO, будет выполняться без перерывов до самого завершения, если она не блокирована вызовом такой операции, как ввод или вывод. Прервать выполнение нити со стратегией FIFO и высоким приоритетом нельзя, и такая нить может значительно снизить общую производительность системы. Никогда не задавайте стратегию FIFO для нитей с большим объемом вычислений (например, обращение большой матрицы) и им подобных.
Стратегия планирования и приоритет нити зависят также и от ее области действия. Применять стратегии FIFO и round-robin можно не всегда.
sched_yield, функция
Функция sched_yield - это эквивалент функции yield для нитей. Функция sched_yield принудительно освобождает процессор и предоставляет возможность планирования других нитей. Следующая запланированная нить может относиться к тому же или к другому процессу. Функцию yield не следует использовать в программах с несколькими нитями.
Интерфейс функции pthread_yield недоступен в спецификации Single UNIX Specification версии 2.