8. Процеси і потоки.
В первых версиях MS-DOS пользователи могли запускать одновременно не более одной программы. Им приходилось ждать, пока она закончит работу, и затем запускать другую. Под Windows, однако, пользователи могут одновременно запускать несколько программ или даже несколько копий одной программы. Отсюда видна одна тонкость, важная для данной главы: в чем различие между программой и процессом? Программа (program) — это статическая последовательность команд, тогда как процесс (process) — это программа и системные ресурсы, необходимые для ее работы.
Процесс является субъектом владения ресурсами и единицей работы. Он служит ОС средством организации многих задач, которые она должна выполнять. ОС выделяет каждому процессу порцию системных ресурсов и гарантирует, что программа каждого процесса будет направляться на исполнение в определенном порядке и своевременно.
В общем случае ОС содержат блок кода, управляющий созданием и удалением процессов, а также отношениями между ними. Этот код называется структурой процессов (process structure) и в Windows NT реализован диспетчером процессов (process manager). Марк Люковски (Mark Lucovsky), один из разработчиков Windows NT, писавший ранее компоненты структуры процессов как для системы UNIX, так и для ОС, основанной на использовании объектов, структурировал и написал диспетчер процессов исполнительной системы NT. Он определил его основную задачу одной фразой; предоставить набор базовых сервисов процесса, который подсистемы среды могли бы использовать для эмуляции своих собственных уникальных структур процессов. Цель такого подхода — обеспечить в Windows NT несколько сред ОС, работающих в пользовательском режиме.
В разных ОС процессы реализованы по-разному. Процессы различаются своим представлением (структурами данных), способами именования и защиты и отношениями между собой. Базовые процессы NT имеют ряд характеристик, отличающих их от процессов других ОС:
• Процессы NT реализованы как объекты, и доступ к ним осуществляется посредством объектных сервисов.
• В адресном пространстве процесса NT может исполняться несколько потоков.
• Как объект-процесс, так и объект-поток имеют встроенные возможности синхронизации.
• Диспетчер процессов NT не поддерживает между создаваемыми им процессами отношений родитель-потомок или каких-либо иных.
В этой главе рассматривается природа процессов вообще и структура процессов исполнительной системы NT в частности. Глава начинается с определения понятия процесса, а затем рассматривается реализация процессов диспетчером процессов NT. И наконец обсуждается соотношение между версией процесса исполнительной системы NT и версиями процессов, которые подсистемы среды предоставляют прикладным программам.
4.1 Что такое процесс?
На самом высоком уровне абстракции процесс состоит из:
• исполняемой программы, которая определяет начальный код и данные;
• закрытого адресного пространства (address space), т. е. набора адресов виртуальной памяти, который процесс может использовать;
• системных ресурсов, таких как семафоры, коммуникационные порты и файлы, выделяемых ОС процессу во время выполнения программы.
В Windows NT процесс, чтобы он мог работать, должен включать четвертый элемент:
• по крайней мере один поток управления (thread of execution).
Поток — это сущность внутри процесса, которую ядро NT направляет на исполнение. Без него программа процесса не может выполняться.
В следующих подразделах процесс рассматривается более детально, начиная с его адресного пространства и заканчивая ресурсами. Затем следует раздел, посвященный теме потоков.
4.1.1 Адресное пространство
Исходя из здравого смысла, какой-либо процесс не должен иметь неограниченного права управления другими процессами. Одним из способов достижения этого в Windows NT служит система виртуальной памяти (virtual memory). С ее помощью программисты (и создаваемые ими процессы) получают логический образ памяти, который не совпадает с ее физической структурой (см. рис. 4-1).
При всяком обращении процесса по виртуальному адресу система виртуальной памяти транслирует этот адрес в физический. Она также предотвращает непосредственный доступ процесса к виртуальной памяти, занятой другими процессами или ОС. Для исполнения кода ОС или доступа к памяти ОС поток должен исполняться в привилегированном режиме процессора — так называемом режиме ядра (kernel mode). Однако большинство процессов — это процессы пользовательского режима, т. е. такие, потоки которых исполняются в основном в непривилегированном режиме процессора — пользовательском режиме (user mode).
Поток пользовательского режима получает доступ к ОС, вызывая некоторый системный сервис. Когда поток вызывает сервис, процесс перехватывает его и переключает из пользовательского режима в режим ядра. ОС получает управление потоком, проверяет аргументы, переданные потоком сервису, после чего исполняет сервис. Перед возвратом управления пользовательской программе ОС переключает поток обратно в пользовательский режим. Таким образом, ОС защищает себя и свои данные от просмотра и модификации пользовательскими процессами.
Данная глава посвящена процессам пользовательского режима, которые в любой момент времени составляют большую часть процессов, исполняемых Windows NT. В пользовательском режиме исполняются как прикладные программы, так и защищенные подсистемы Windows NT. Последние представляют собой процессы-серверы пользовательского режима, реализующие важные функции системы. Они реализованы как серверы, чтобы упростить базовую ОС и обеспечить ее расширяемость. Подсистемы работают в пользовательском режиме, так что адресное пространство каждой из них защищено от прикладных процессов и от других подсистем (подробнее см. гл. 5).
Рис. 4-1. Виртуальная и физическая память.
4.1.2 Набор ресурсов
Кроме закрытого адресного пространства, с каждым процессом связан набор разнообразных системных ресурсов. На рис. 4-2 показан типичный процесс и его ресурсы.
Вверху схемы изображен маркер доступа процесса, описанный в гл. 3, "Диспетчер объектов и контроль доступа". Обратите внимание, что маркер доступа присоединяется к процессу непосредственно ОС. Если процессу требуется получить информацию о его маркере доступа или, возможно, изменить некоторые атрибуты маркера, то он должен открыть описатель своего объекта-маркера. Подсистема защиты определяет, есть ли у процесса такое право. Процесс, показанный на рисунке, не открыл описатель своего маркера доступа, поэтому отсутствует стрелка, идущая из таблицы объектов к маркеру.
Ниже маркера доступа расположен набор структур данных, созданных диспетчером виртуальной памяти для отслеживания виртуальных адресов, используемых процессом. Процесс не может напрямую читать или изменять эти структуры; диспетчер виртуальной памяти создает и модифицирует их неявно, по мере выделения памяти программой. (Эти структуры данных более подробно описаны в гл. 6, "Диспетчер виртуальной памяти".)
Таблица объектов процесса показана в нижней части рисунка. Процесс открыл описатели одного из своих потоков, файла и секции совместно используемой памяти. (Описание виртуального адресного пространства содержит информацию о виртуальных адресах, занятых стеком потока и объектом-секцией, на что указывают стрелки, идущие от описания виртуального адресного пространства к этим объектам.)
Кроме материально осязаемых ресурсов, показанных на рисунке, каждый процесс имеет набор квот на ресурсы, ограничивающий объем памяти, который его потоки могут использовать для открытия описателей объектов. Помимо этого, у каждого процесса есть базовый приоритет и процессорное сродство по умолчанию, описанные далее в этой главе.
Рис. 4-2, Процесс и его ресурсы.