Опубликован: 28.06.2006 | Уровень: специалист | Доступ: платный | ВУЗ: Московский государственный технический университет им. Н.Э. Баумана
Лекция 11:

Основы многозадачности

< Лекция 10 || Лекция 11: 12 || Лекция 12 >

Реализация в Windows

В современных полновесных реализациях Windows (Windows 2000, Windows XP, Windows 2003) планировщик ядра выделяет процессорное время потокам. Управление волокнами возложено на приложения пользователя: Windows предоставляет набор функций, с помощью которых приложение может управлять созданными волокнами. Фактически для волокон реализуется невытесняющая многозадачность средствами приложения; с точки зрения операционной системы, все волокна должны быть созданы в рамках потоков (один поток может быть "расщеплен" на множество волокон средствами приложения) и система никак не вмешивается в их планирование.

В Windows определен список событий, которые приводят к перепланированию потоков:

  • создание и завершение потока;
  • выделенный потоку квант исчерпан;
  • поток вышел из состояния ожидания;
  • поток перешел в состояние ожидания;
  • изменен приоритет потока;
  • изменена привязка к процессору.

В целях уменьшения затрат на планирование потоков несколько изменен граф состояний потока. На рис. 6.6 приведен "классический" вид графа состояний задачи, а на рис. 6.8 - граф состояний потока в Windows. Переход из состояния "готовность" в состояние "выполнение" сделан в два этапа - выбранный к выполнению поток подготавливается к выполнению и переводится в состояние "выбран"; эта подготовка может осуществляться до наступления момента перепланирования, и в нужный момент достаточно просто переключить контекст выполняющегося потока на выбранный.

Граф состояний потока

Рис. 6.8. Граф состояний потока

Также в два этапа может происходить переход из состояния "ожидание" в "готовность": если ожидание было долгим, то стек потока может быть выгружен из оперативной памяти. В этом случае поток переводится в промежуточное состояние до завершения загрузки стека - в списке готовых к выполнению потоков находятся только те, которые можно начать выполнять без лишнего ожидания.

При выборе потока для выполнения учитываются приоритеты потоков (абсолютные приоритеты) - система начинает выполнять код потока с наибольшим приоритетом из числа готовых к исполнению.

Процесс выбора потока для выполнения усложняется в случае SMP систем, когда помимо приоритета готового к исполнению потока учитывается, на каком процессоре ранее выполнялся код данного потока.

В Windows выделяют понятие "идеального" процессора - им назначается процессор, на котором запускается приложение в первый раз. В дальнейшем система старается выполнять код потока именно на этом процессоре - для SMP систем это решение улучшает использование кэш-памяти, а для NUMA систем позволяет, по большей части, ограничиться использованием оперативной памяти, локальной для данного процессора. Заметим, что диспетчер памяти Windows при выделении памяти для запускаемого процесса старается учитывать доступность памяти для назначенного процессора в случае NUMA системы.

В многопроцессорной системе используется либо первый простаивающий процессор, либо, при необходимости вытеснения уже работающего потока, проверяются идеальный процессор, последний использовавшийся и процессор с наибольшим номером. Если на одном из них работает поток с меньшим приоритетом, то последний вытесняется и заменяется новым потоком; в противном случае выполнение потока откладывается (даже если в системе есть процессоры, занятые потоками с меньшим приоритетом).

Современные реализации Windows в рамках единого дерева кодов могут быть использованы для различных классов задач - от рабочих станций, обслуживающих преимущественно интерфейс пользователя, до серверных установок на многопроцессорных машинах. Чтобы можно было эффективно использовать одну ОС в столь разных классах систем, планировщик Windows динамически изменяет длительность квантов и приоритеты, назначаемые потокам. Администратор системы может в некоторой степени изменить поведение системы при назначении длительности квантов и приоритетов потоков.

Управление квантованием

Квантование потоков осуществляется по тикам системного таймера, продолжительность одного тика составляет обычно 10 или 15 мс, больший по продолжительности тик назначают многопроцессорным машинам. Каждый тик системного таймера соответствует 3 условным единицам; величина кванта может варьироваться от 2 до 12 тиков (от 6 до 36 единиц).

Параметр реестра HKLM\SYSTEM\CurrentControlSet\Control\PriorityControl\ Win32PrioritySeparation предназначен для управления квантованием. На рис. 6.9 дан формат этого параметра для Windows 2000-2003, а в таблице 6.1 приводятся длительности квантов в условных единицах для разных значений полей параметра Win32PrioritySeparation.

Управление квантованием в Windows (длительность кванта показана в табл. 6.1)

Рис. 6.9. Управление квантованием в Windows (длительность кванта показана в табл. 6.1)
Таблица 6.1. Длительность кванта
Короткий квант Длинный квант
Значение младших 2-х бит параметра Win32PrioritySeparation 0 1 2 0 1 2
Переменная длительность 6 12 18 12 24 36
Фиксированная длительность 18 18 18 36 36 36

Этот параметр может быть изменен с помощью панели управления, однако, лишь в очень ограниченных рамках:

"System Properties|Advanced|Performance:Settings|Advanced|Adjust for best performance of:" позволяет выбрать только:

  • "applications"

    Короткие кванты переменной длины, значение 0x26 т.е. 10 01 10 (короткие кванты переменной длительности, 18 ед.).

  • "background services"

    Длинные кванты фиксированной длины, значение 0x18 т.е. 01 10 00 (длинные кванты фиксированной длительности, 36 ед.). Более тонкая настройка возможна с помощью редактора реестра.

Управление длительностью кванта связано с активностью процесса, которая определяется наличием интерфейса пользователя (GUI или консоль) и его активностью. Если процесс находится в фоновом режиме, то длительность назначенного ему кванта соответствует "нулевым" колонкам таблицы 6.1 (выделены серым цветом; т.е. длительности 6 или 12 - для переменной длины кванта или 18 и 36 - для фиксированной). Когда процесс становится активным, то ему назначается продолжительность квантов, исходя из значения двух младших бит параметра Win32PrioritySeparation в соответствии с приведенной таблицей.

Еще один случай увеличения длительности кванта - процесс долгое время не получал процессорного времени (это может случиться, если все время есть активные процессы более высокого приоритета). В этой ситуации система раз в 3-4 секунды (в зависимости от продолжительности тика) назначает процессу повышенный приоритет и квант удвоенной длительности. По истечении этого кванта приоритет возвращается к прежнему значению и восстанавливается рекомендуемая длительность кванта.

Управление приоритетами

В Windows выделяется 32 уровня приоритетов. 0 соответствует самому низкому приоритету (с таким приоритетом работает только специальный поток обнуления страниц), 31 - самому высокому. Этот диапазон делится на три части:

  • Приоритет 0 - соответствует приоритету потока обнуления страниц.
  • Приоритеты с 1 по 15 - соответствуют динамическим уровням приоритетов. Большинство потоков работают именно в этом диапазоне приоритетов, и Windows может корректировать в некоторых случаях приоритеты потоков из этого диапазона.
  • Приоритеты с 16 по 31 - соответствуют приоритетам "реального времени". Этот уровень достаточно высок для того, чтобы поток, работающий с таким приоритетом, мог реально помешать нормальной работе других потоков в системе - например, помешать обрабатывать сообщения от клавиатуры и мыши. Windows самостоятельно не корректирует приоритеты этого диапазона.

Для некоторого упрощения управления приоритетами в Windows выделяют "классы приоритета" (priority class), которые задают базовый уровень приоритета, и "относительные приоритеты" потоков, которые корректируют указанный базовый уровень. Операционная система предоставляет набор функций для управления классами и относительными приоритетами потоков.

Планировщик операционной системы также может корректировать уровень приоритета (из диапазона 1-15), однако базовый уровень (т.е. класс) не может быть изменен. Такая коррекция приоритета выполняется в случае:

  • Завершения операции ввода-вывода - в зависимости от устройства, приоритет повышается на 1 - 8 уровней.
  • По окончании ожидания события или семафора (см. далее) - на один уровень.
  • При пробуждении GUI потоков - на 2 уровня.
  • По окончании ожидания потоком активного процесса (определяется по активности интерфейса) - на величину, указанную младшими 2 битами параметра Win32PrioritySeparation (см. управление длительностью кванта).

В случае коррекции приоритета по одной из перечисленных причин, повышенный приоритет начинает постепенно снижаться до начального уровня потока - с каждым тиком таймера на один уровень.

Еще один случай повышения приоритета (вместе с увеличением длительности кванта) - процесс долгое время не получал процессорного времени. В этой ситуации система раз в 3-4 секунды назначает процессу приоритет, равный 15, и квант удвоенной длительности. По истечении этого кванта приоритет возвращается к прежнему значению и восстанавливается рекомендуемая длительность кванта.

Разработчик приложения может изменять класс приоритета, назначенный процессу, и относительный приоритет потоков в процессе в соответствии с приведенной таблицей 6.2. Планировщик при выборе потока для исполнения учитывает итоговый уровень приоритета.

Таблица 6.2. Соответствие классов приоритета и относительных приоритетов потоков уровням
Уровень Класс приоритета (задает базовый уровень приоритета)
REALTIME 24 HIGH 13 ABOVE_NORMAL 10 NORMAL BELOW_NORMAL 6 IDLE 4
Foreground 9 Normal 8 Background 7
31 TIME_CRITICAL

Уровни приоритета с 16 по 31 отведены только для класса REALTIME_PRIORITY_CLASS

Не рекомендуется создавать потоки с таким классом приоритета, так как это может повлиять на обработку сообщений от клавиатуры, мыши, сохранение на диске данных кэша и т.д.
30 6
29 5
28 4
27 3
26 HIGHEST
25 ABOVE_NORMAL
24 NORMAL (24)
23 BELOW_NOR-MAL
22 LOWEST
21 -3
20 -4
19 -5
18 -6
17 -7
16 IDLE
15 TIME_CRI-TICAL TIME_CRI-TICAL TIME_CRI-TICAL TIME_CRI-TICAL TIME_CRI-TICAL TIME_CRI-TICAL TIME_CRI-TICAL
14 ABOVE_NOR-MAL
13 NORMAL (13)
12 BELOW_NOR-MAL HIGHEST
11 LOWEST ABOVE_NOR-MAL HIGHEST
10 NORMAL (10) ABOVE_NOR-MAL HIGHEST
9 BELOW_NOR-MAL NORMAL (9) ABOVE_NOR-MAL HIGHEST
8 LOWEST BELOW_NOR-MAL NORMAL (8) ABOVE_NOR-MAL HIGHEST
7 LOWEST BELOW_NOR-MAL NORMAL (7) ABOVE_NOR-MAL
6 LOWEST BELOW_NOR-MAL NORMAL (6) HIGHEST
5 LOWEST BELOW_NOR-MAL ABOVE_NOR-MAL
4 LOWEST NORMAL (4)
3 BELOW_NOR-MAL
2 LOWEST
1 IDLE IDLE IDLE IDLE IDLE IDLE IDLE
0 приоритет потока обнуления страниц

В зависимости от настройки планировщика, NORMAL_PRIORITY_CLASS с базовым уровнем приоритета 8 может быть "расщеплен" на два базовых уровня - для потоков активных процессов (базовый уровень 9) и для потоков фоновых процессов (базовый уровень 7). Для класса HIGH_PRIORITY_CLASS относительные приоритеты потока THREAD_PRIORITY_HIGHEST и THREAD_PRIORITY_TIME_CRITICAL дают одинаковое значение приоритета 15.

< Лекция 10 || Лекция 11: 12 || Лекция 12 >
Анастасия Булинкова
Анастасия Булинкова
Рабочим названием платформы .NET было
Bogdan Drumov
Bogdan Drumov
Молдова, Республика
Azamat Nurmanbetov
Azamat Nurmanbetov
Киргизия, Bishkek