Вопрос 18. Реализация процессов в ОС Windows.

Внутреннее устройство процессов в ОС Windows

В 32-разрядной версии системы у каждого процесса сеть 4-гигабаит-ное адресное пространство, в котором пользовательский код занимает нижние 2 гигабайта (в серверах — 3 Гб). В своем адресном пространстве, которое представляет собой набор регионов и описывается специальны¬ми структурами данных (см. «Система управления памятью»), процесс содержит потоки, учетную информацию и ссылки на ресурсы, которые обобществляются всеми потоками процесса.

Блок управления процессом (РСВ) реализован в виде набора связан¬ных структур, главная из которых называется блоком процесса EPROCESS. Соответственно, каждый поток также представлен набором структур во главе с блоком потока ETHREAD. Эти наборы данных, за исключением блоков переменных окружения процесса и потока (РЕВ и ТЕВ), существу¬ют в системном адресном пространстве (рис. 2).

Содержимое блока EPROCESS подробно описано в [Руссинович]. Блок PROCESS (на рис. справа), блок переменных окружения про¬цесса (РЕВ) и структура данных, поддерживаемая подсистемой Win32 (блок процесса Win32), содержат дополнительные сведения об объекте «процесс».

Идентификатор процесса кратен четырем и используется в роли байтового индекса в таблицах ядра наравне с другими объектами.

Создание процесса

Обычно процесс создается другим процессом вызовом WIN32-функции CivateProcess (а также CreateProcessAsUser и CreateProcessWithLogOnW). Созда¬ние процесса осуществляется в несколько этапов.

На первом этапе, выполняемом библиотекой kernel32.dll в режиме пользователя, на диске отыскивается нужный файл-образ, после чего создается объект «раздел» памяти для его проецирования на адресное про¬странство нового процесса.

На втором этапе выполняется обращение к системному сервису NTCreateProcess для создания объекта «процесс». Формируются блоки EPROCESS, KPROCESS и блок переменных окружения РЕВ. Менеджер процессов инициализирует в блоке процесса маркер доступа (копируя аналогичный маркер родительского процесса), идентификатор и другие поля.

На третьем этапе в уже полностью проинициализированном объек¬те «процесс» необходимо создать первичный поток. Это, посредством си¬стемного сервиса NtCreateThread делает библиотека kernel32.dl.

Затем kernel32.dll посылает подсистеме Win32 сообщение, которое содержит информацию, необходимую для выполнения нового процесса. Данные о процессе и потоке помешаются, соответственно, в список про¬цессов и список потоков данного процесса, затем устанавливается при¬оритет процесса, создастся структура, используемая той частью полсисте¬мы Win32, которая работает в режиме ядра, и т. д.

Наконец, запускается первичный поток, для чего формируются его на¬чальный контекст и стек, и выполняется запуск стартовой процедуры пото¬ка режима ядра KiThreadStartup. После этого стартовый код из библиотеки C/C++ передаст управление функции main() запускаемой программы.

Функция CreateProcess

Таким образом, если приложение намерено создать новый процесс, один из его потоков должен обратиться к WIN32-функции CreateProcess.

BOOL CreateProcess(

PCTSTR pszApplicationName, PTSTR pszCommandLine, PSECURITY_ATTRIBUTES psaProcess, PSECURITY_ATTRIBUTES psaThread, BOOL BInheritHandles, DWORD fdwCreate, PVOID pvEnvironment, PCTSTR pszCurDir, PSTARTUPINFO psiStartlnfo, PPROCESS_INFORMATION ppiProcInfo);

Описание параметров функции можно посмотреть в MSDN.

Формально ОС Windows не поддерживает какой-либо иерархии процессов, например, отношений «родительский - дочерний». Однако негласная иерархия, заключающаяся в том, кто чьим дескриптором (описателем) владеет, все же существует. Например, владение дескриптором процесса позволяет влиять на его адресное пространство и функционирование. В данном случае описатель дочернего процесса возвращается создающему процессу в составе параметра ppiProcInfo. Хотя он не может быть напрямую передан другому процессу, тем не менее имеется возможность передать другому процессу его дубликат. Таким путем при необходимости в группе процессов может быть сформирована нужная иерархия.