На самом высоком уровне абстракции процесс в Windows включает следующее:
- закрытое виртуальное адресное пространство — диапазон адресов виртуальной памяти, которым может пользоваться процесс;
- исполняемую программу — начальный код и данные, проецируемые на виртуальное адресное пространство процесса;
- список открытых описателей различных системных ресурсов - семафоров, коммуникационных портов, файлов и других объектов, доступных всем потокам в данном процессе;
- контекст защиты, называемый маркером доступа и идентифицирующий пользователя, группы безопасности и привилегии, сопоставленные с процессом;
- уникальный идентификатор процесса (во внутрисистемной терминологии называемый идентификатором клиента);
- минимум один поток.
Поток — некая сущность внутри процесса, получающая процессорное время для выполнения. Без потока программа процесса не может выполняться. Поток включает следующие наиболее важные элементы:
- содержимое набора регистров процессора, отражающих состояние процессора;
- два стека, один из которых используется потоком при выполнении в режиме ядра, а другой — в пользовательском режиме;
- закрытую область памяти, называемую локальной памятью потока и используемую подсистемами, библиотеками исполняющих систем и DLL;
- уникальный идентификатор потока (во внутрисистемной терминологии также называемый идентификатором клиента: идентификаторы процессов и потоков генерируются из одного пространства имен и никогда не перекрываются);
- иногда потоки обладают своим контекстом защиты, который обычно используется многопоточными серверными приложениями, подменяющими контекст защиты обслуживаемых клиентов.
Переменные регистры, стеки и локальные области памяти называются контекстом потока. Хотя у потоков свой контекст выполнения, каждый поток внутри одного процесса делит его виртуальное адресное пространство (а также остальные ресурсы, принадлежащие процессу). Это означает, что все потоки в процессе могут записывать и считывать содержимое памяти любого из потоков данного процесса. Однако потоки не могут случайно сослаться на адресное пространство другого процесса. Исключение возможно в ситуации, когда тот предоставляет часть своего адресного пространства как раздел общей памяти, в Windows API называемый объектом «проекция файла». Каждый процесс в Windows представлен блоком процесса, создаваемым исполнительной системой.
Планирование потоков
Выбранный поток работает в течении кванта времени. Квант зависит от:
- Конфигурационных параметров
- Статуса процесса
- Использования объекта задание
Код отвечающий за планирование рассредоточен по ядру, совокупность процедур, выполняющих планирование, называется диспетчером ядра.
Код Windows, отвечающий за планирование, реализован в ядре. Поскольку этот код рассредоточен по ядру, единого модуля или процедуры с названием «планировщик» нет. Совокупность процедур, выполняющих эти обязанности, называется диспетчерам ядра. Диспетчеризация потоков может быть вызвана любым из следующих событий:
- Поток готов к выполнению — например, он только что создан или вышел из состояния ожидания.
- Поток выходит из состояния Running (выполняется), так как его квант истек или поток завершается либо переходит в состояние ожидания.
- Приоритет потока изменяется в результате вызова системного сервиса или самой Windows.
- Изменяется привязка к процессорам, из-за чего поток больше не может работать на процессоре, на котором он выполнялся.
Планирование в Windows осуществляется на уровне потоков.
Поскольку решения, принимаемые в ходе планирования, касаются исключительно потоков, система не обращает внимания на то, какому процессу принадлежит тот или иной поток. Так, если у процесса А есть 10, у процесса В — 2 готовых к выполнению потока, и все 12 имеют одинаковый приоритет, каждый из потоков теоретически получит 1/12 процессорного времени, потому что Windows не станет поровну делить процессорное время между двумя процессами.
Уровни приоритета
Windows API сначала упорядочивает процессы по классам приоритета, назначенным при их создании [Real-time (реального времени), High (высокий), Above Normal (выше обычного), Normal (обычный), Below Normal (ниже обычного) и Idle (простаивающий)], а затем — по относительному приоритету индивидуальных потоков в рамках этих процессов [Time-critical (критичный по времени), Highest (наивысший), Above-normal (выше обычного), Normal (обычный), Below-normal (ниже обычного), Lowest (наименьший) и Idle (простаивающий)].
Рисунок 3 – Уровни приоритетов в ОС Windows
Базовый приоритет каждого потока в Windows API устанавливается, исходя из класса приоритета его процесса и относительного приоритета самого потока. Если у процесса только одно значение приоритета (базовое), то у каждого потока их два: текущее и базовое. Решения, связанные с планированием, принимаются на основе текущего приоритета. В определенных обстоятельствах система может на короткое время повышать приоритеты потоков в динамическом диапазоне (1-15). Windows никогда не изменяет приоритеты потоков в диапазоне реального времени (16-31), поэтому у таких потоков базовый приоритет идентичен текущему.
Многие важные системные потоки режима ядра выполняются в диапазоне приоритетов реального времени. Поэтому, если потоки слишком долго выполняются с приоритетом этого диапазона, они могут блокировать критичные системные функции (например в диспетчере памяти, диспетчере кэша или драйверах устройств).