Переключение контекста

Контекст потока и процедура его переключения зависят от архитектуры процессора. B типичном случае переключение контекста требует сохранения и восстановления следующих данных:

указателя команд;

указателей на стек ядра и пользовательский стек;

указателя на адресное пространство, в котором выполняется поток (каталог таблиц страниц процесса).

Ядро сохраняет эту информацию, заталкивая ее в текущий стек ядра, обновляя указатель стека и сохраняя его в блоке KTHREAD потока. Далее указатель стека ядра устанавливается на стек ядра нового потока и загружается контекст этого потока. Если новый поток принадлежит другому процессу, в специальный регистр процессора загружается адрес его каталога таблиц страниц, в результате чего адресное пространство этого процесса становится доступным (о трансляции адресов см. в главе 7). При наличии отложенной APC ядра запрашивается прерывание IRQL уровня 1. B ином случае управление передается загруженному для нового потока указателю команд, и выполнение этого потока возобновляется.

Поток простоя

Если нет ни одного потока, готового к выполнению на процессоре, Windows подключает к данному процессору поток простоя (процесса Idle). Для каждого процессора создается свой поток простоя.

Разные утилиты для просмотра процессов в Windows по-разному называют процесс Idle. Диспетчер задач и Process Explorer обозначают его как «System Idle Process», Process Viewer — как «Idle», Pstat — как «Idle Process», Process Explode и Tlist — как «System Process», a Qslice — как «SystemProcess». Windows сообщает, что приоритет потока простоя равен 0. Ho на самом деле у него вообще нет уровня приоритета, поскольку он выполняется лишь в отсутствие других потоков. (Вспомните, что на нулевом уровне приоритета в Windows работает лишь поток обнуления страниц; см. главу 7.)

Холостой цикл, работающий при IRQL уровня «DPC/dispatch», просто запрашивает задания, например на доставку отложенных DPC или на поиск потоков, подлежащих диспетчеризации.

Хотя последовательность работы потока простоя зависит от архитектуры, он все равно выполняет следующие действия.

1. Включает и отключает прерывания (тем самым давая возможность доставить отложенные прерывания).

2. Проверяет, нет ли у процессора незавершенных DPC (см. главу 3). Если таковые есть, сбрасывает отложенное программное прерывание и доставляет эти DPC

3. Проверяет, выбран ли какой-нибудь поток для выполнения на данном процессоре, и, если да, организует его диспетчеризацию.

4. Вызывает из HAL процедуру обработки процессора в простое (если нужно выполнить какие-либо функции управления электропитанием).

B Windows Server 2003 поток простоя также проверяет наличие потоков, ожидающих выполнения на других процессорах, но об этом пойдет речь в разделе по планированию потоков в многопроцессорных системах.

Динамическое повышение приоритета

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

после завершения операций ввода-вывода;

по окончании ожидания на событии или семафоре исполнительной системы;

по окончании операции ожидания потоками активного процесса;

при пробуждении GUI-потоков из-за операций с окнами;

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

Динамическое повышение приоритета предназначено для оптимизации общей пропускной способности и отзывчивости системы, а также для устранения потенциально «нечестных» сценариев планирования. Однако, как и любой другой алгоритм планирования, динамическое повышение приоритета — не панацея, и от него выигрывают не все приложения.

ПРИМЕЧАНИЕ Windows никогда не увеличивает приоритет потоков в диапазоне реального времени (16–31). Поэтому планирование таких потоков по отношению к другим всегда предсказуемо. Windows считает: тот, кто использует приоритеты реального времени, знает, что делает.

Динамическое повышение приоритета после завершения ввода-вывода

Windows временно повышает приоритет потоков по окончании определенных операций ввода-вывода, поэтому у потоков, ожидавших завершения таких операций, больше шансов немедленно возобновить выполнение и обработать полученные данные. Вспомните: после пробуждения потока оставшийся у него квант уменьшается на одну единицу, так что потоки, ожидавшие завершения ввода-вывода, не получают неоправданных преимуществ. Хотя рекомендованные приращения в результате динамического повышения приоритета определены в заголовочных файлах DDK (ищите строки «#define IO» в Wdm.h или Ntddk.h; эти же значения перечислены в таблице 6-17), реальное приращение определяется драйвером устройства. Именно драйвер устройства указывает — через функцию ядра IoCompleteRequest — на необходимость динамического повышения приоритета после выполнения запроса на ввод-вывод. Заметьте, что для запросов на ввод-вывод, адресованных устройствам, которые гарантируют меньшее время отклика, предусматриваются большие приращения приоритета.


Логин
Пароль
Запомнить меня