Какие параметры характеризуют процесс в операционной системе windows

Работа операционной системы Windows основана на работе процессов. В этой статье разберём что такое Windows процессы, их свойства, состояния и другое

Работа операционной системы Windows основана на работе процессов. В этой статье разберём что такое Windows процессы, их свойства, состояния и другое.

Процессы

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

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

Windows процессы состоят из следующего:

  • Закрытое виртуальное адресное пространство, то есть выделенная для процесса часть оперативной памяти, которая называется виртуальной.
  • Исполняемая программа выполняя свой код, помещает его в виртуальную память.
  • Список открытых дескрипторов. Процесс может открывать или создавать объекты, например файлы или другие процессы. Эти объекты нумеруются, и их номера называют дескрипторами. Ссылаться на объект по дескриптору быстрее, чем по имени.
  • Контекст безопасности. Сюда входит пользователь процесса, группа, привилегии, сеанс и другое.
  • Идентификатор процесса, то есть его уникальный номер.
  • Программный поток (как минимум один или несколько). Чтобы процесс хоть что-то делал, в нем должен существовать программный поток. Если потока нет, значит что-то пошло не так, возможно процесс не смог корректно завершиться, или стартовать.

У процессов есть еще очень много свойств которые вы можете посмотреть в “Диспетчере задач” или “Process Explorer“.

Процесс может быть в различных состояниях:

  • Выполняется — обычно все фоновые процессы будут в этом состоянии, а если процесс с окошком, то значит что приложение готово принимать данные от пользователя.
  • Приостановлен — означает что все потоки процесса находятся в приостановленном состоянии. Приложения Windows Apps переходят в это состояние при сворачивании окна для экономии ресурсов.
  • Не отвечает — означает что программный поток не проверял свою очередь сообщений более 5 секунд. Поток может быть занят работой и интенсивно загружать процессор, или может ожидать операции ввода/вывода. При этом окно приложения зависает.

В Windows существуют процессы трёх типов:

  • Приложения. Процессы запущенных приложений. У таких приложений есть окно на рабочем столе, которое вы можете свернуть, развернуть или закрыть.
  • Фоновые процессы. Такие процессы работают в фоне и не имеют окна. Некоторые процессы приложений становятся фоновыми, когда вы сворачиваете их в трей.
  • Процессы Windows. Процессы самой операционной системы, например “Диспетчер печати” или “Проводник”.

Дерево процессов

В Windows процессы знают только своих родителей, а более древних предков не знают.

Например у нас есть такое дерево процессов:

Процесс_1
|- Процесс_2
  |- Процесс_3

Если мы завершим дерево процессов “Процесс_1“, то завершатся все процессы. Потому что “Процесс_1” знает про “Процесс_2“, а “Процесс_2” знает про “Процесс_3“.

Если мы вначале завершим “Процесс_2“, а затем завершаем дерево процессов “Процесс_1“, то завершится только “Процесс_1“, так как между “Процесс_1” и “Процесс_3” не останется связи.

Например, запустите командную строку и выполните команду title parrent чтобы изменить заголовок окна и start cmd чтобы запустить второе окно командной строки:

>title parrent
>start cmd

Измените заголовок второго окна на child и из него запустите программу paint:

>title child
>mspaint

В окне командной строке child введите команду exit, окно закроется а paint продолжит работать:

>exit

После этого на рабочем столе останутся два приложения, командная строка parrent и paint. При этом parrent будет являться как бы дедом для paint.

Запустите “Диспетчер задач”, на вкладке “Процессы” найдите процесс “Обработчик команд Windows”, разверните список и найдите “parrent“. Затем нажмите на нём правой копкой мыши и выберите “Подробно”:

Подробности по процессу parrent

Вы переключитесь на вкладку “Подробно” с выделенным процессом “cmd.exe“. Нажмите правой кнопкой по этому процессу и выберите «Завершить дерево процессов»:

Завершаем дерево процессов в диспетчере задач

Окно командной строки Parrent завершится а Paint останется работать. Так мы убедились что связи между первым процессом и его внуком нет, если у внука нет непосредственного родителя.

Потоки

На центральном процессоре обрабатываются не сами процессы, а программные потоки. Каждый поток, это код загруженный программой. Программа может работать в одном потоке или создавать несколько. Если программа работает в несколько потоков, то она может выполняться на разных ядрах процессора. Посмотреть на потоки можно с помощью программы Process Explorer.

Поток содержит:

  • два стека: для режима ядра и для пользовательского режима;
  • локальную памятью потока (TLS, Thread-Local Storage);
  • уникальный идентификатор потока (TID, Thread ID).

Приложение может создать дополнительный поток, например, когда у приложения есть графический интерфейс, который работает в одном потоке и ожидает от пользователя ввода каких-то данных, а второй поток в это время занимается обработкой других данных.

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

  • svchost.exe — главный процесс для служб Windows.
  • dllhost.exe — отвечает за обработку приложений, использующих динамически подключаемые библиотеки. Также отвечает за COM и .NET. И ещё управляет процессами IIS.
  • lsass.exe — отвечает за авторизацию локальных пользователей, попросту говоря без него вход в систему для локальных пользователей будет невозможен.

Волокна и планирование пользовательского режима

Потоки выполняются на центральном процессоре, а за их переключение отвечает планировщик ядра. В связи с тем что такое переключение это затратная операция. В Windows придумали два механизма для сокращения таких затрат: волокна (fibers) и планирование пользовательского режима (UMS, User Mode Scheduling).

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

Потоки UMS (User Mode Scheduling), доступные только в 64-разрядных версиях Windows, предоставляют все основные преимущества волокон при минимуме их недостатков. Потоки UMS обладают собственным состоянием ядра, поэтому они «видимы» для ядра, что позволяет нескольким потокам UMS совместно использовать процессор и конкурировать за него. Работает это следующим образом:

  • Когда двум и более потокам UMS требуется выполнить работу в пользовательском режиме, они сами могут периодически уступать управление другому потоку в пользовательском режиме, не обращаясь к планировщику. Ядро при этом думает что продолжает работать один поток.
  • Когда потоку UMS все таки нужно обратиться к ядру, он переключается на специально выделенный поток режима ядра.

Задания

Задания Windows (Job) позволяют объединить несколько процессов в одну группу. Затем можно этой группой управлять:

  • устанавливать лимиты (на память или процессорное время) для группы процессов входящих в задание;
  • останавливать, приостанавливать, запускать такую группу процессов.

Посмотреть на задания можно с помощью Process Explorer.

Диспетчер задач

Чаще всего для получения информации о процессе мы используем «Диспетчер задач». Запустить его можно разными способами:

  • комбинацией клавиш Ctrl+Shift+Esc;
  • щелчком правой кнопкой мыши на панели задач и выборе «Диспетчер задач»;
  • нажатием клавиш Ctrl+Alt+Del и выборе «Диспетчер задач»;
  • запуском исполняемого файла C:Windowssystem32Taskmgr.exe.

При первом запуске диспетчера задач он запускается в кратком режиме, при этом видны только процессы имеющие видимое окно. При нажатие на кнопку «Подробнее» откроется полный режим:

Краткий режим Диспетчера задач

В полном режиме на вкладке «Процессы» виден список процессов и информация по ним. Чтобы получить больше информации можно нажать правой кнопкой мышки на заголовке и добавить столбцы:

Диспетчер задач - Добавление столбцов с информацией

Чтобы получить еще больше информации можно нажать правой кнопкой мышки на процессе и выбрать «Подробно». При этом вы переключитесь на вкладку «Подробности» и этот процесс выделится.

На вкладке «Подробности» можно получить ещё больше информации о процессе. А также здесь также можно добавить колонки с дополнительной информацией, для этого нужно щелкнуть правой кнопкой мыши по заголовку и нажать «Выбрать столбцы»:

Выбор столбцов с информацией о процессах на вкладке «Подробности»

Process Explorer

Установка и подготовка к работе

Более подробную информацию о процессах и потоках можно получить с помощью программы Process Explorer из пакета Sysinternals. Его нужно скачать и запустить.

Некоторые возможности Process Explorer:

  • информация по правам процесса: кто владелец процесса, у кого есть доступ к нему;
  • выделение разными цветами процессов и потоков, для удобного восприятия информации:
    • процессы служб – розовый;
    • ваши собственные процессы – синий;
    • новые процессы – зелёный;
    • завершенные процессы – красный;
  • список файлов открытых процессом;
  • возможность приостановки процесса или потока;
  • возможность уничтожения отдельных потоков;
  • поиск процессов создающих наибольшую нагрузку на процессор;
  • отображение списка процессов в виде дерева, а также алфавитная сортировка и сортировка в обратном порядке;
  • возможность посмотреть:
    • число дескрипторов у процесса;
    • активность потоков в процессе;
    • подробную информация о распределении памяти.

Запустите Process Explorer:

Process Explorer

Далее нужно настроить сервер символических имен. Если это не сделать, при двойном щелчке на процессе, на вкладке Threads (потоки) вы получите сообщение о том, что символические имена не настроены:

Предупреждение о не настроенных символических именах

Для начала скачиваем установщик «Пакет SDK для Windows 10».

Устанавливать все не нужно, достаточно при установки выбрать “Debugging Tools for Windows“:

Установка SDK для Windows 10

Для настройки символических имен перейдите в меню Options / Configure / Symbols. Введите путь к библиотеке Dbghelp.dll, которая находится внутри установленного «Пакета SDK для Windows 10» по умолчанию:

  • C:Program Files (x86)Windows Kits10Debuggersx64Dbghelp.dll.

И путь к серверу символической информации:

  • srv*C:Symbols*http://msdl.microsoft.com/download/symbols

При этом:

  • C:Symbols — путь к кеширующей локальной папке;
  • http://msdl.microsoft.com/download/symbols — сервер microsoft.

Настройка символический имен в Process Explorer

Некоторые основные настройки Process Explorer:

  • Смена цветового выделения – Options / Configure Colors.
  • Выбор колонок с информацией о процессах – View / Select Columns.
  • Сортировка процессов – нужно щелкнуть на заголовке столбца Process, при первом щелчке сортировка будет в алфавитном порядке, при втором в обратном порядке, при третьем вернется в вид дерева.
  • Просмотр только своих процессов – View / снять галочку Show Processes from All Users.
  • Настройка времени выделения только что запущенных процессов и завершённых – Options / Difference Highlight Duration / введите количество секунд.
  • Чтобы исследователь процесс подробнее можно дважды щелкнуть на нем и посмотреть информацию на различных вкладках.
  • Открыть нижнюю панель для просмотра открытых дескрипторов или библиотек – Vies / Show Lower Panel.

Потоки в Process Explorer

Потоки отдельного процесса можно увидеть в программе Process Explorer. Для этого нужно дважды кликнуть по процессу и в открывшемся окне перейти на вкладку «Threads»:

Process Explorer (потоки процесса)

В колонках видна информация по каждому потоку:

  • TID — идентификатор потока.
  • CPU — загрузка процессора.
  • Cycles Delta — общее количество циклов процессора, которое этот процесс использовал с момента последнего обновления работы Process Explorer. Скорость обновления программы можно настроить, указав например 5 минут.
  • Suspend Count — количество приостановок потока.
  • Service — название службы.
  • Start Address — начальный адрес процедуры, который начинает выполнение нового потока. Выводится в формате:«модуль!функция».

При выделении потока, снизу показана следующую информация:

Изучение активности потока

  • Идентификатор потока.
  • Время начала работы потока.
  • Состояние потока.
  • Время выполнения в режиме ядра и в пользовательском режиме.
  • Счетчик переключения контекста для центрального процессора.
  • Количество циклов процессора.
  • Базовый приоритет.
  • Динамический приоритет (текущий).
  • Приоритет ввода / вывода.
  • Приоритет памяти.
  • Идеальный процессор (предпочтительный процессор).

Есть также кнопки:

Устройство Windows. Изучение активности потока, изображение №3

  • Stack — посмотреть стек процесса;
  • Module — посмотреть свойства запущенного исполняемого файла;
  • Permission — посмотреть права на поток;
  • Kill — завершить поток;
  • Suspend — приостановить поток.

Задания в Process Explorer

Process Explorer может выделить процессы, управляемые заданиями. Чтобы включить такое выделение откройте меню «Options» и выберите команду «Configure Colors», далее поставьте галочку «Jobs»:

Process Explorer — выделение заданий

Более того, страницы свойств таких процессов содержат дополнительную вкладку Job с информацией о самом объекте задания. Например приложение Skype работает со своими процессами как за заданием:

Process Explorer — вкладка Job

Запустите командную строку и введите команду:

>runas /user:<домен><пользователь> cmd

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

В новой командной строке запустите блокнот:

>notepad.exe

Далее запускаем Process Explorer и находим такое дерево процессов:

Устройство Windows. Задания, изображение №3

Как видим, процесс cmd и notepad это процессы связанные с каким-то заданием. Если дважды кликнуть по любому из этих процессов и перейти на вкладку Job, то мы увидим следующее:

Process Explorer — вкладка Job

Тут видно что эти два процесса работают в рамках одного задания.

Вернуться к оглавлению

Сводка

Процессы Windows

Имя статьи

Процессы Windows

Описание

Работа операционной системы Windows основана на работе процессов. В этой статье разберём что такое Windows процессы, их свойства, состояния и другое

С точки зрения
программирования каждый процесс win32/64
включает компоненты (рис. 22):

  • один или несколько
    потоков;

  • виртуальное
    адресное пространство, отличное от
    адресных пространств других процессов,
    за исключением случаев явного разделения
    памяти;

  • один или более
    сегментов кода, включая код DLL;

Рис. 22. Структура
процесса и его потоков

  • один
    или более сегментов данных, содержащих
    глобальные переменные;

  • строки окружения
    с информацией о переменных окружениях,
    таких как текущий путь поиска файла и
    др.;

  • память кучи
    процесса;

  • ресурсы процесса
    (открытые дескрипторы, файлы, другие
    кучи).

Атрибуты процесса
и потока в Windows
приведены в табл. 2.

Атрибуты процесса
и потока в Windows
Таблица 2

Процесс

Поток

Идентификатор процесса — уникальное
значение, идентифицирующее процесс
в ОС

Идентификатор потока — уникальное
значение, идентифицирующее поток,
когда он вызывает сервис.

Дескриптор защиты – описывает, кто
создал процесс, права доступа и пр.

Контекст потока – набор значений
регистров, которыми определяется
состояние выполняемого потока.

Базовый приоритет – базовый приоритет
для потоков

Динамический приоритет — приоритет
выполняемого потока в данный момент.

Базовый
приоритет – нижний приоритет
динамического приоритета потока.

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

Родственность процессов по потоку –
множество процессов, где возможно
выполнение потоков.

Время выполнения – суммарное время,
затраченное на выполнение всех потоков
в процессе.

Время выполнения потока — совокупное
время, затраченное на выполнение
потока в пользовательском режиме и
режиме ядра.

Счётчик ввода/вывода — переменные, в
которые заносятся сведения о количестве
и типе операций ввода/вывода, выполненных
потоками процесса.

Статус извещения (оповещения) – этот
флаг, который указывает, следует ли
потоку выполнять асинхронный вызов
процедуры.

Счётчик операций с виртуальной памятью
– это переменные, в которые заносятся
сведения о количестве и типе операций
с виртуальной памятью выполненных
потоками процесса.

Счётчик приостановок – в нём указывается,
сколько раз выполнение потока было
приостановлено без последующего
возобновления.

Квоты – максимальное количество
страничной памяти и процессорного
времени доступного процессу

Маркеры режима анонимного воплощения
– это временный признак доступа.

Порты исключения/отладки – это каналы
обмена информацией между процессами,
в которые диспетчер процессов должен
отправлять сообщения при возникновении
исключительных ситуаций одного из
потоков процесса.

Порт завершения – это канал обмена
информацией между процессами, куда
диспетчер процессов отправляет
сообщения при завершении потока.

Статус выхода –
причины завершения процесса

Статус выхода –
причины завершения потока

Все потоки процесса
совместно используют код, глобальные
переменные, строки окружения и ресурсы
процесса [3].
Каждый поток планируется независимо.
Поток включает следующие элементы:

  • стек вызова
    процедур, переменных, обработчиков
    исключений и автоматических данных;

  • локальная память
    потока – это массивы указателей, которые
    дают возможность процессу выделить
    память для создания собственного
    уникального окружения данных потока;

  • структура контекста,
    управляемая ядром, содержащая значение
    аппаратных регистров.

Некоторые атрибуты
потока подобны атрибутам процессов.
Значениия таких атрибутов потока
извлекаются из значений атрибутов
процесса. Например, в многопроцессорной
системе родственные процессоры по
потоку – это множество процессоров, на
которых может выполняться данный поток.
Оно совпадает с множеством процессоров
родственных по процессу или является
его подмножеством. Информация, содержащаяся
в контексте потока, позволяет ОС
приостанавливать и возобновлять потоки
[9].
Основные функции управления процессами
и потоками показаны в табл.3.

Сервисы процесса
и потока в Windows
Таблица 3

Процесс

Поток

Создание процесса CreateProcess().

Создание потока CreateThread().

Открытие процесса OpenProcess().

Открытие потока OpenThread()

Информация по запросу процесса

Информация по запросу потока

Информация по наладке процесса

Информация по наладке потока

Текущий процесс
GetCurrentProcessID()

Текущий поток GetCurrentThreadID()

Прекращение процесса
ExitProcess()

Завершение потока ExitThread()

Получение контекста

Установка контекста

Приостановка Delay()

Возобновление

Извещение потоков

Проверка извещения потока

Порт регистрации завершения.

Основной функцией
для управления процессом win32 является
функция CreateProcess(). Она создаёт процесс
с одним потоком. Так как процесс требует
наличие кода, то в вызове функции
CreateProcess() необходимо указывать имя
исполняемого файла программы. Функция
имеет 10 параметров и при успешном
выполнении возвращает дескрипторы для
процесса и для первичного потока.
Дополнительные потоки можно создать
функцией CreateThread(). Для Windows
все процессы одинаковы, и она не различает
дочерние и родительские, в отличие от
Unix.

Жизненный цикл
потока в Windows
(рис 23) проходит следующие шесть состояний
[3]:

Готовый к
выполнению: это поток, который может
быть направлен на выполнение, у него
есть все необходимые ресурсы кроме
процессорного времени. Диспетчер
микроядра отслеживает, все готовые
потоки и осуществляет их планирование
в соответствии с их приоритетом.

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

Рис. 23. Жизненный
путь потока в Windows

Выполняющийся:
как только микроядро переключит поток,
резервный поток перейдёт в состояние
выполнения и будет в нём находится, пока
не произойдёт одно из событий: поток
будет вытеснен более приоритетным
потоком, если закончится квант времени,
будет блокирован или завершён.

Ожидающее:
поток входит в состояние ожидания, если
он блокирован каким-либо событием
(например, операцией ввода/вывода); он
добровольно ждёт синхронизации; среда
подсистемы предписывает потоку, чтобы
он сам себя остановил. После удовлетворения
условий ожидания, поток переходит в
состояние готовности, если все его
ресурсы доступны.

Переходное:
поток готов к выполнению, но не все
ресурсы необходимые ему для работы
доступны. При доступности всех ресурсов
он переходит в состояние готовности.

Завершающее:
завершение потока может быть инициировано
самим потоком, другим процессом или
может произойти вместе с завершением
родительского процесса.

После завершения
необходимых операций освобождения
ресурсов поток удаляется из операционной
системы.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]

  • #
  • #
  • #
  • #
  • #
  • #
  • #
  • #
  • #
  • #
  • #

ГЛABA 6 Процессы, потоки и задания

B этой главе мы рассмотрим структуры данных и алгоритмы, связанные с процессами, потоками и заданиями в Microsoft Windows. B первом разделе основное внимание уделяется внутренним структурам данных, из которых состоит процесс. Bo втором разделе поясняются этапы создания процесса (и его первичного потока). Далее поясняются внутреннее устройство потоков и их планирование. Завершается глава описанием объекта «задание» Job object).

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

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

B этом разделе описываются ключевые структуры данных процессов Windows. Также поясняются основные переменные ядра, счетчики производительности, функции и утилиты, имеющие отношение к процессам.

Структуры данных

Каждый процесс в Windows представлен блоком процесса, создаваемым исполнительной системой (EPROCESS). Кроме многочисленных атрибутов, относящихся к процессу, в блоке EPROCESS содержатся указатели на некоторые структуры данных. Так, у каждого процесса есть один или более потоков, представляемых блоками потоков исполнительной системы (ETH-READ) (см. раздел «Внутреннее устройство потоков» далее в этой главе). Блок EPROCESS и связанные с ним структуры данных — за исключением блока переменных окружения процесса Oprocess environment block, PEB) — существуют в системном пространстве. PEB находится в адресном пространстве процесса, так как содержит данные, модифицируемые кодом пользовательского режима.

Для каждого процесса, выполняющего Windows-программу, процесс подсистемы Windows (Csrss) поддерживает в дополнение к блоку EPROCESS параллельную структуру данных. Кроме того, часть подсистемы Windows, работающая в режиме ядра (Win32k.sys), поддерживает структуру данных для каждого процесса, которая создается при первом вызове потоком любой функции USER или GDI, реализованной в режиме ядра.

Ha рис. 6–1 показана упрощенная схема структур данных процесса и потока. Каждая из этих структур детально рассматривается далее в этой главе.

Рис. 6–1. Структуры данных, сопоставляемые с процессами и потоками

Сначала рассмотрим блок процесса. (Изучение блока потока мы отложим до раздела «Внутреннее устройство потоков».) Ключевые поля EPROCESS показаны на рис. 6–2.

ЭКСПЕРИМЕНТ: исследуем формат блока EPROCESS

Список полей, составляющих блок EPROCESS, и их смещения в шестнадцатеричной форме, можно увидеть с помощью команды dt eprocess отладчика ядра (подробнее об отладчике ядра см. главу 1). Вот что дает эта команда (вывод обрезан для экономии места):

Заметьте, что первое поле (Pcb) на самом деле является подструктурой — блоком процесса, принадлежащим ядру (KPROCESS). Именно здесь хранится информация, используемая при планировании. Для вывода формата блока процесса KPROCESS введите dt_kprocess:

Другой способ просмотра KPROCESS (и прочих подструктур в EPROCESS) — использовать ключ рекурсии (-r) в команде dt. Например, введя dt _eprocess — r1, вы увидите все подструктуры с глубиной вложения, равной 1.

Команда dt показывает формат блока процесса, но не его содержимое. Чтобы вывести экземпляр самого процесса, можно указать адрес структуры EPROCESS в качестве аргумента команды dt. Команда !process 0 0 позволяет получить адрес всех блоков EPROCESS в системе. Пример вывода этой команды будет приведен далее в этой главе.

Некоторые поля, показанные в предыдущем эксперименте, поясняются в таблице 6–1. Процессы и потоки — неотъемлемая часть Windows, о которой нельзя рассказать, не упомянув множество других компонентов системы. Ho, чтобы эта глава не слишком разбухла, мы поясняем механизмы, связанные с процессами и потоками (вроде управления памятью, защиты, объектов и описателей), в других главах.

Таблица 6–1. Содержимое блока EPROCESS

Блок KPROCESS, входящий в блок EPROCESS, и РЕВ, на который указывает EPROCESS, содержат дополнительные сведения об объекте «процесс». Блок KPROCESS, иногда называемый блоком управления процессом Oprocess control block, PCB), показан на рис. 6–3. Он содержит базовую информацию, нужную ядру Windows для планирования потоков. (O каталогах страниц см. главу 7.)

РЕВ, размещаемый в адресном пространстве пользовательского процесса, содержит информацию, необходимую загрузчику образов, диспетчеру кучи и другим системным DLL-модулям Windows для доступа из пользовательского режима. (Блоки EPROCESS и KPROCESS доступны только из режима ядра.) Базовая структура РЕВ, показанная на рис. 6–4, подробнее объясняется далее в этой главе.

ЭКСПЕРИМЕНТ: исследуем PEB

Дамп структуры PEB можно получить с помощью команды !peb отладчика ядра. Чтобы узнать адрес РЕВ, используйте команду !process так:

Переменные ядра

B таблице 6–2 перечислено несколько важнейших глобальных переменных ядра, связанных с процессами. Ha эти переменные мы будем ссылаться по ходу изложения материала, в частности при описании этапов создания процесса.

Таблица 6–2. Переменные ядра, связанные с процессами

Счетчики производительности

Windows поддерживает несколько счетчиков, которые позволяют отслеживать процессы, выполняемые в системе; данные этих счетчиков можно считывать программно или просматривать с помощью оснастки Performance. B таблице 6–3 перечислены счетчики производительности, имеющие отношение к процессам (кроме счетчиков, связанных с управлением памятью и вводом-выводом, которые описываются в главах 7 и 9 соответственно!

Сопутствующие функции

B таблице 6–4 приведена информация по некоторым Windows-функциям, связанным с процессами. Более подробные сведения см. в документации Windows API в MSDN Library.

ЭКСПЕРИМЕНТ: применение команды !process отладчика ядра

Эта команда выводит подмножество информации из блока EPROCESS. Ee вывод для каждого процесса делится на две части. Сначала вы видите часть, показанную ниже (если вы не указываете адрес или идентификатор процесса, команда !process выводит сведения для активного процесса на текущем процессоре).

Вслед за базовой информацией о процессе появляется список его потоков. Данная часть поясняется в эксперименте «Применение команды !thread отладчика ядра» далее в этой главе. Еще одна команда, позволяющая получить информацию о процессе, — !handle. Она создает дамп таблицы описателей, принадлежащей процессу (см. раздел «Описатели объектов и таблица описателей, принадлежащая процессу» главы 3). Структуры защиты процессов и потоков описываются в главе 8.

Что делает функция CreateProcess

K этому моменту мы уже рассмотрели структуры, которые являются частью процесса, и API-функции, позволяющие вам (и операционной системе) манипулировать процессами. Вы также научились пользоваться различными утилитами для наблюдения за тем, как процессы взаимодействуют с системой. Ho как эти процессы появляются на свет и как они завершаются, выполнив задачи, для которых они предназначались? B следующих разделах вы узнаете, как порождаются Windows-процессы.

Создание Windows-процесса осуществляется вызовом одной из таких функций, как CreateProcess, CreateProcessAsUser, CreateProcessWithTokenW или CreateProcessWitbLogonW, и проходит в несколько этапов с участием трех компонентов операционной системы: Kernel32.dll (библиотеки клиентской части Windows), исполнительной системы и процесса подсистемы окружения Windows (Csrss). Поскольку архитектура Windows поддерживает несколько подсистем окружения, операции, необходимые для создания объекта «процесс» исполнительной системы (которым могут пользоваться и другие подсистемы окружения), отделены от операций, требуемых для создания Windows-процесса. Поэтому часть действий Windows-функции CreateProcess специфична для семантики, привносимой подсистемой Windows.

B приведенном ниже списке перечислены основные этапы создания процесса Windows-функцией CreateProcess. Детальное описание действий на каждом этапе дается в следующих разделах.

ПРИМЕЧАНИЕ Многие этапы работы CreateProcess связаны с подготовкой виртуального адресного пространства процесса и поэтому требуют понимания массы структур и терминов, связанных с управлением памятью и описываемых в главе 7.

1. Открывается файл образа (EXE), который будет выполняться в процессе.

2. Создается объект «процесс» исполнительной системы.

3. Создается первичный поток (стек, контекст и объект «поток» исполнительной системы).

4. Подсистема Windows уведомляется о создании нового процесса и потока.

5. Начинается выполнение первичного потока (если не указан флаг CREATE_SUSPENDED).

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

Общая схема создания процесса в Windows показана на рис. 6–5. Прежде чем открыть исполняемый образ для выполнения, CreateProcess делает следующее.

При вызове CreateProcess класс приоритета указывается в параметре CreationFlags, и, вызывая CreateProcess, вы можете задать сразу несколько классов приоритета. Windows выбирает самый низкий из них.

Когда для нового процесса не указывается класс приоритета, по умолчанию принимается Normal, если только класс приоритета процесса-создателя не равен IdIe или Below Normal. B последнем случае новый процесс получает тот же класс приоритета, что и у родительского процесса.

Если для нового процесса указан класс приоритета Real-time, а создатель не имеет привилегии Increase Scheduling Priority, устанавливается класс приоритета High. Иначе говоря, функция CreateProcess завершается успешно, даже если у того, кто ее вызвал, недостаточно привилегий для создания процессов с классом приоритета Real-time, — просто класс приоритета нового процесса будет ниже Real-time.

Все окна сопоставляются с объектами «рабочий стол», которые являются графическим представлением рабочего пространства. Если при вызове CreateProcess не указан конкретный объект «рабочий стол», новый процесс сопоставляется с текущим объектом «рабочий стол» процесса-создателя.

Этап 1: открытие образа, подлежащего выполнению

Как показано на рис. 6–6 и в таблице 6–5, на первом этапе CreateProcess должна найти нужный Windows-образ, который будет выполнять файл, указанный вызвавшим процессом, и создать объект «раздел» для его последующего проецирования на адресное пространство нового процесса. Если имя образа не указано, используется первая лексема командной строки (первая часть командной строки, которая заканчивается пробелом или знаком табуляции и является допустимой в качестве имени образа).

B Windows XP и Windows Server 2003 CreateProcess проверяет, не запрещает ли политика безопасности на данной машине запуск этого образа (см. главу 8).

Если в качестве исполняемого файла указана Windows-программа, ее имя используется напрямую. A если исполняемый файл является не Windows-приложением, а программой MS-DOS, Winl6 или POSIX, то CreateProcess ищет образ поддержки (support image) для запуска этой программы. Данный процесс необходим потому, что приложения, не являющиеся Windows-программами, нельзя запускать напрямую. Вместо этого Windows использует один из нескольких специальных образов поддержки, которые и отвечают за запуск приложений, отличных от Windows-программ. Так, если вы пытаетесь запустить POSIX-приложение, CreateProcess идентифицирует его как таковое и вызывает исполняемый Windows-файл поддержки POSIX, Posix.exe. A если вы запускаете программу MS-DOS или Winl6, стартует исполняемый Windows-файл поддержки Ntvdm.exe. Короче говоря, вы не можете напрямую создать процесс, не являющийся Windows-процессом. Если Windows не найдет соответствующий файл поддержки, вызов CreateProcess закончится неудачей.

Конкретное решение о запуске того или иного файла поддержки CreateProcess принимает так.

Если исполняемый файл — программа MS-DOS с расширением EXE, COM или PIF, подсистеме Windows посылается сообщение, чтобы она проверила, не создан ли уже процесс поддержки MS-DOS (Ntvdm.exe, указанный в параметре реестра HKLMSYSTEMCurrentControlSetControlWOWCmdline). Если да, этот процесс используется для запуска программы MS-DOS — подсистема Windows посылает виртуальной DOS-машине (Virtual DOS Machine, VDM) сообщение для запуска новой программы, — после чего управление возвращается к CreateProcess. Если нет, запускается Ntvdm.exe и повторно выполняется первый этап CreateProcess.

Если исполняемый файл — командный файл с расширением BAT или CMD, запускается Cmd.exe, обрабатывающий командную строку Windows, и повторно выполняется первый этап CreateProcess. (Имя командного файла передается Cmd.exe как первый параметр.)

Если исполняемый файл — приложение Winl6 (Windows 3.1), CreateProcess решает, надо ли для его запуска создавать новый процесс VDM или оно должно использовать глобальный для всех сеансов процесс VDM (который, возможно, еще не создан). Решение определяется флагами CREATE_SEPARATE_WOW_VDM и CREATE_SHARED_WOW_VDM. Если эти флаги не заданы, то по умолчанию решение принимается, исходя из значения параметра реестра HKLMSYSTEMCurrentControlSetControlWOWDefaultSeparateVDM. Если программа будет работать в отдельной VDM, запускается приложение, указанное в HKLMSYSTEMCurrentControlSetControlWOWWowCmdline, и повторно выполняется первый этап CreateProcess. B ином случае подсистема Windows посылает сообщение для проверки возможности использования общего процесса VDM. (Это исключено, если процесс VDM сопоставлен с другим объектом «рабочий стол» или если его параметры защиты отличны от таковых для вызывающего процесса. Тогда нужно создавать новый процесс VDM.) Если задействовать общий процесс VDM нельзя, подсистема Windows посылает ему сообщение о необходимости запуска нового образа, и управление возвращается к CreateProcess. Если процесс VDM еще не создан (или если он существует, но использовать его нельзя), запускается образ поддержки VDM и повторно выполняется первый этап CreateProcess. K этому моменту CreateProcess успешно открывает допустимый исполняемый файл Windows и создает для него объект «раздел». Этот объект еще не спроецирован на память, но уже открыт. Однако сам факт успешного создания объекта «раздел» не означает того, что запускаемый файл является допустимым Windows-образом, — он может быть DLL или исполняемым файлом POSIX. Если это исполняемый файл POSIX, запускается Posix.exe, и CreateProcess заново выполняет действия первого этапа. A если это DLL, вызов CreateProcess заканчивается неудачей.

CreateProcess, найдя допустимый исполняемый Windows-образ, ищет в разделе реестра HKLMSOFTWAREMicrosoftWindows NTCurrentVersionImage File Execution Options подраздел с именем и расширением запускаемого образа (но без указания пути к нему, например Image.exe). Если такой подраздел есть, CreateProcess ищет в нем параметр Debugger. Если он присутствует, его значение становится именем запускаемого образа, после чего следует повторение первого этапа CreateProcess.

СОВЕТ Вы можете извлечь выгоду из такого поведения CreateProcess. Оно позволяет отлаживать стартовый код процессов сервисов Windows перед их запуском. Если бы вы подключили отладчик лишь после запуска сервиса, это исключило бы возможность отладки стартового кода.

Этап 2: создание объекта «процесс»

K началу второго этапа функция CreateProcess уже открыла допустимый исполняемый файл Windows и создала объект «раздел» для его проецирования на адресное пространство нового процесса. После этого она создает объект «процесс», чтобы запустить образ вызовом внутренней функции NtCreateProcess. Создание объекта «процесс» исполнительной системы включает следующие подэтапы:

формируется блок EPROCESS;

создается начальное адресное пространство процесса; инициализируется блок процесса ядра (KPROCESS);

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

формируется блок РЕВ;

завершается инициализация объекта «процесс» исполнительной системы.

ПРИМЕЧАНИЕ Родительские процессы отсутствуют только при инициализации системы. Далее они всегда используются для задания контекстов защиты новых процессов.

Этап 2A: формирование блока EPROCESS

Этот подэтап включает девять операций.

1. Создается и инициализируется блок EPROCESS.

2. От родительского процесса наследуется маска привязки к процессорам.

3. Минимальный и максимальный размеры рабочего набора процесса устанавливаются равными значениям переменных PsMinimumWorkingSet и PsMaximumWorkingSet.

4. Блок квот нового процесса настраивается на адрес блока квот его родительского процесса и увеличивается счетчик ссылок на блок квот последнего.

5. Наследуется пространство имен устройств Windows (в том числе определение букв дисков, СОМ-портов и т. д.).

6. B поле InheritedFromUniqueProcessId нового объекта «процесс» сохраняется идентификатор родительского процесса.

7. Создается основной маркер доступа процесса (копированием аналогичного маркера родительского процесса). Новый процесс наследует профиль защиты своих родителей. Если используется функция CreateProcessAsUser, чтобы задать для нового процесса другой маркер доступа, он соответственно модифицируется.

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

9. Статус завершения нового процесса устанавливается как STATUSPENDING.

Этап 2B: создание начального адресного пространства процесса

Начальное адресное пространство процесса состоит из следующих страниц:

каталога страниц (этих каталогов может быть больше одного в системах, где таблицы страниц имеют более двух уровней, например в х86-систе-мах в режиме PAE или в 64-разрядных системах);

страницы гиперпространства;

списка рабочего набора.

Для создания этих страниц выполняются операции, перечисленные ниже.

1. B соответствующих таблицах страниц формируются записи, позволяющие проецировать эти начальные страницы. Количество страниц вычитается из переменной ядра MmTotalCommittedPages и добавляется к переменной ядра MmProcessCommit.

2. Из MmResidentAvailablePages вычитается минимальный размер рабочего набора по умолчанию (PsMinimumWorkingSef).

3. Ha адресное пространство процесса проецируются страницы таблицы страниц для неподкачиваемой части системного пространства и системного кэша.

Этап 2C: создание блока процесса ядра

Ha этом подэтапе работы CreateProcess инициализируется блок KPROCESS, содержащий указатель на список потоков ядра. (Ядро не имеет представления об описателях, поэтому оно обходит их таблицу.) Блок процесса ядра также указывает на каталог таблицы страниц процесса (используемый для отслеживания виртуального адресного пространства процесса) и содержит суммарное время выполнения потоков процесса, базовый приоритет процесса по умолчанию (он начинается с Normal, или 8, если только его значение у родительского процесса не равно IdIe или Below Normal; в последнем случае приоритет просто наследуется), привязку потоков к процессорам по умолчанию и начальный квант процессорного времени, выделяемый процессу по умолчанию. Последнее значение принимается равным PspForegroundQuantum[0], первому элементу общесистемной таблицы величин квантов.

ПРИМЕЧАНИЕ Начальный квант по умолчанию в клиентских и серверных версиях Windows неодинаков. Подробнее о квантах см. раздел «Планирование потоков» далее в этой главе.

Этап 2D: инициализация адресного пространства процесса

Подготовка адресного пространства нового процесса довольно сложна, поэтому разберем ее отдельно по каждой операции. Для максимального усвоения материала этого раздела вы должны иметь представление о внутреннем устройстве диспетчера памяти Windows (см. главу 7).

Диспетчер виртуальной памяти присваивает времени последнего усечения (last trim time) для процесса текущее время. Диспетчер рабочих наборов, выполняемый в контексте системного потока диспетчера настройки баланса (balance set manager), использует это значение, чтобы определить, когда нужно инициировать усечение рабочего набора.

Диспетчер памяти инициализирует список рабочего набора процесса, после чего становится возможной генерация ошибок страниц.

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

Ha адресное пространство процесса проецируется Ntdll.dll.

Ha адресное пространство процесса проецируются общесистемные таблицы NLS (national language support).

ПРИМЕЧАНИЕ Процессы POSIX клонируют адресное пространство своих родителей, поэтому для них не нужны все вышеперечисленные операции создания нового адресного пространства. B случае приложений POSIX базовый адрес раздела нового процесса приравнивается тому же базовому адресу родительского процесса, а родительский PEB просто копируется.

Этап 2E: формирование блока PEB

CreateProcess выделяет страницу под PEB и инициализирует некоторые поля, описанные в таблице 6–6.

Если в файле явно указаны значения версии Windows, эти данные замещают соответствующие начальные значения, показанные в таблице 6–6. Связь полей версии из заголовка образа с полями PEB описывается в таблице 6–7.

Таблица 6–7. Windows-значения, заменяющие начальные значения полей PEB

Этап 2F: завершение инициализации объекта «процесс» исполнительной системы

Перед возвратом описателя нового процесса выполняется несколько завершающих операций.

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

2. Если родительский процесс входил в задание, новый процесс тоже включается в это задание (о заданиях — в конце главы).

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

4. Если в образе явно указана маска привязки к процессорам (например, в поле конфигурационного заголовка), ее значение копируется в PEB и впоследствии устанавливается как маска привязки к процессорам по умолчанию.

5. CreateProcess помещает блок нового процесса в конец списка активных процессов (PsActiveProcessHead).

6. Устанавливается время создания процесса, и вызвавшей функции (CreateProcess в Kernel32.dll) возвращается описатель нового процесса.

Этап 3: создание первичного потока, его стека и контекста

K началу третьего этапа объект «процесс» исполнительной системы полностью инициализирован. Однако у него еще нет ни одного потока, поэтому он не может ничего делать. Прежде чем создать поток, нужно создать стек и контекст, в котором он будет выполняться. Эта операция и является целью данного этапа. Размер стека первичного потока берется из образа — другого способа задать его размер нет.

Далее создается первичный поток вызовом NtCreateThread. Параметр потока — это адрес PEB (данный параметр нельзя задать при вызове CreateProcess — только при вызове CreateThread). Этот параметр используется кодом инициализации, выполняемым в контексте нового потока (см. этап 6). Однако поток по-прежнему ничего не делает — он создается в приостановленном состоянии и возобновляется лишь по завершении инициализации процесса (см. этап 5). NtCreateThread вызывает PspCreateThread (функцию, которая используется и при создании системных потоков) и выполняет следующие операции.

1. Увеличивается счетчик потоков в объекте «процесс».

2. Создается и инициализируется блок потока исполнительной системы (ETHREAD).

3. Генерируется идентификатор нового потока.

4. B адресном пространстве пользовательского режима формируется TEB.

5. Стартовый адрес потока пользовательского режима сохраняется в блоке ETHREAD. B случае Windows-потоков это адрес системной стартовой функции потока в Kernel32.dll (BaseProcessStart) первого потока в процессе и BaseThreadStart для дополнительных потоков). Стартовый адрес, указанный пользователем, также хранится в ETHREAD, но в другом его месте; это позволяет системной стартовой функции потока вызвать пользовательскую стартовую функцию.

6. Для подготовки блока KTHREAD вызывается KeInitThread. Начальный и текущий базовые приоритеты потока устанавливаются равными базовому приоритету процесса; привязка к процессорам и значение кванта также устанавливаются по соответствующим параметрам процесса. Кроме того, функция определяет идеальный процессор для первичного потока. (O том, как происходит выбор идеального процессора см. раздел «Идеальный и последний процессоры» далее в этой главе.) Затем KeInitThread создает стек ядра для потока и инициализирует его аппаратно-зависимый контекст, включая фреймы ловушек и исключений. Контекст потока настраивается так, чтобы выполнение этого потока началось в режиме ядра в KiThreadStartup. Далее KeInitThread устанавливает состояние потока в Initialized (инициализирован) и возвращает управление PspCreateThread.

7. Вызываются общесистемные процедуры, зарегистрированные на уведомление о создании потока.

8. Маркер доступа потока настраивается как указатель на маркер доступа процесса. Затем вызывающая программа проверяется на предмет того, имеет ли она право создавать потоки. Эта проверка всегда заканчивается успешно, если поток создается в локальном процессе, но может дать отрицательный результат, если поток создается в другом процессе через функцию CreateRemoteThread и у создающего процесса нет привилегии отладки.

9. Наконец, поток готов к выполнению.

Этап 4: уведомление подсистемы Windows о новом процессе

Если заданы соответствующие правила, для нового процесса создается маркер с ограниченными правами доступа. K этому моменту все необходимые объекты исполнительной системы созданы, и Kernel32.dll посылает подсистеме Windows сообщение, чтобы она подготовилась к выполнению нового процесса и потока. Сообщение включает следующую информацию:

описатели процесса и потока;

флагисоздания;

идентификатор родительского процесса;

флаг, который указывает, относится ли данный процесс к Windows-приложениям (что позволяет Csrss определить, показывать ли курсор запуска). Получив такое сообщение, подсистема Windows выполняет следующие операции.

1. CreateProcess дублирует описатели процесса и потока. Ha этом этапе счетчик числа пользователей процесса увеличивается с 1 (начального значения, установленного в момент создания процесса) до 2.

2. Если класс приоритета процесса не указан, CreateProcess устанавливает его в соответствии с алгоритмом, описанным ранее.

3. Создается блок процесса Csrss.

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

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

6. Создается и инициализируется блок потока Csrss.

7. CreateProcess включает поток в список потоков процесса.

8. Увеличивается счетчик процессов в данном сеансе.

9. Уровень завершения процесса process shutdown level) устанавливается как 0x280 (это значение по умолчанию; его описание ищите в документации MSDN Library по ключевому слову SetProcessShutdownParameters).

10. Блок нового процесса включается в список общесистемных Windows-процессов.

11. Создается и инициализируется структура данных fW32PROCESS), индивидуальная для каждого процесса и используемая той частью подсистемы Windows, которая работает в режиме ядра.

12. Выводится курсор запуска в виде стрелки с песочными часами. Тем самым Windows говорит пользователю: «Я запускаю какую-то программу, но ты все равно можешь пользоваться курсором.» Если в течение двух секунд процесс не делает GUI-вызова, курсор возвращается к стандартному виду. A если за это время процесс обратился к GUI, CreateProcess ждет открытия им окна в течение пяти секунд и после этого восстанавливает исходную форму курсора.

Этап 5: запуск первичного потока

K началу этого этапа окружение процесса уже определено, его потокам выделены ресурсы, у процесса есть поток, а подсистеме Windows известен факт существования нового процесса. Поэтому для завершения инициализации нового процесса (см. этап 6) возобновляется выполнение его первичного потока, если только не указан флаг CREATE_SUSPENDED.

Этап 6: инициализация в контексте нового процесса

Новый поток начинает свою жизнь с выполнения стартовой процедуры потока режима ядра, KiTbreadStartup, которая понижает уровень IRQL потока с «DPC/dispatch» до «APC», а затем вызывает системную стартовую процедуру потока, PspUserTbreadStartup. Параметром этой процедуры является пользовательский стартовый адрес потока.

B Windows 2000 PspUserTbreadStartup сначала разрешает расширение рабочего набора. Если создаваемый процесс является отлаживаемой программой, все его потоки (которые могли быть созданы на этапе 3) приостанавливаются. B отладочный порт процесса (порт функций подсистемы Windows, так как это Windows-процесс) посылается сообщение о создании процесса, чтобы подсистема доставила событие отладки CREATE_PROCESS_DEBUGINFO соответствующему отладчику. Далее PspUserTbreadStartup ждет пересылки подсистемой Windows ответа отладчика (через функцию ContinueDebugEvent). Как только такой ответ приходит, выполнение всех потоков возобновляется.

B Windows XP и Windows Server 2003 PspUserThreadStartup проверяет, разрешена ли в системе предварительная выборка для приложений (application prefetching), и, если да, вызывает модуль логической предвыборки (logical prefetcher) для обработки файла команд предвыборки (prefetch instruction file) (если таковой есть), а затем выполняет предвыборку страниц, на которые процесс ссылался в течение первых десяти секунд при последнем запуске. Наконец, PspUserThreadStartup ставит APC пользовательского режима в очередь для запуска процедуры инициализации загрузчика образов (LdrInitializeThunk из Ntdll.dll). APC будет доставлен, когда поток попытается вернуться в пользовательский режим.

Когда PspUserThreadStartup возвращает управление KiTbreadStartup, та возвращается из режима ядра, доставляет APC и обращается к LdrInitialize-Thunk. Последняя инициализирует загрузчик, диспетчер кучи, таблицы NLS, массив локальной памяти потока (thread-local storage, TLS) и структуры критической секции. После этого она загружает необходимые DLL и вызывает их точки входа с флагом DLL_PROCESS_ATTACH.

Наконец, когда процедура инициализации загрузчика возвращает управление диспетчеру APC пользовательского режима, начинается выполнение образа в пользовательском режиме. Диспетчер APC вызывает стартовую функцию потока, помещенную в пользовательский стек в момент доставки APC.

Сборки, существующие в нескольких версиях

Одна из проблем, уже давно изводившая пользователей Windows, — так называемый «DLL hell». Вы создаете этот ад, устанавливая приложение, которое заменяет одну или более базовых системных DLL, содержащих, например, стандартные элементы управления, исполняющую среду Microsoft Visual Basic или MFC Программы установки приложений делают такую замену, чтобы приложения работали корректно, но обновленные DLL могут оказаться несовместимыми с уже установленными приложениями.

Эта проблема в Windows 2000 была отчасти решена, где модификация базовых системных DLL предотвращалась средством Windows File Protection, а приложениям разрешалось использовать собственные экземпляры этих DLL. Чтобы задействовать свой экземпляр какой-либо DLL вместо того, который находится в системном каталоге, у приложения должен быть файл Application.exe.local (где Application — имя исполняемого файла приложения); этот файл указывает загрузчику сначала проверить DLL-модули в каталоге приложения. Такой вид переадресации DLL позволяет избежать проблем несовместимости между приложениями и DLL, но больно бьет по принципу разделения DLL, ради которого DLL изначально и разрабатывались. Кроме того, любые DLL, загруженные из списка KnownDLLs (они постоянно проецируются в память) или, наоборот, загруженные ими, нельзя переадресовывать по такому механизму.

Продолжая работу над решением этой проблемы, Microsoft ввела в Windows XP общие сборки (shared assemblies). Сборка (assembly) состоит из группы ресурсов, в том числе DLL и XML-файла манифеста, который описывает сборку и ее содержимое. Приложение ссылается на сборку через свой XML-манифест. Манифестом может быть файл в каталоге приложения с тем же именем, что и само приложение, но с добавленным расширением «.manifest» (например application.exe.ma-nifest), либо он может быть включен в приложение как ресурс. Манифест описывает приложение и его зависимости от сборок.

Существует два типа сборок: закрытые (private) и общие (shared). Общие сборки отличаются тем, что они подписываются цифровой подписью; это позволяет обнаруживать их повреждение или модификацию. Помимо этого, общие сборки хранятся в каталоге WindowsWinsxs, тогда как закрытые — в каталоге приложения. Таким образом, с общими сборками сопоставлен файл каталога (.cat), содержащий информацию о цифровых подписях. Общие сборки могут содержать несколько версий какой-либо DLL, чтобы приложения, зависимые от определенной версии этой DLL, всегда могли использовать именно ее.

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

Пример общей сборки — 6-я версия DLL стандартных элементов управления Windows, comctl32.dll, которая является новинкой Windows XP. Ee файл манифеста называется WindowsWinsxsManifestx86_Microsoft.Windows.CommonControls_6595b64144ccfldf_6.0.0.0_x-ww_1382d70a.manifest. C ним сопоставлен файл каталога (с тем же именем, но с расширением. cat) и подкаталог в Winsxs, включающий comctl32.dll.

Comctl32.dll версии 6 обеспечивает интеграцию с темами Windows XP и из-за того, что приложения, написанные без учета поддержки тем, могут неправильно выглядеть на экране при использовании этой новой DLL, она доступна только тем приложениям, которые явно ссылаются на ее общую сборку. Версия Comctl32.dll, установленная в Win-dowsSystem32, — это экземпляр версии 5.x, не поддерживающей темы. Загружая приложение, загрузчик ищет его манифест и, если таковой есть, загружает DLL-модули из указанной сборки. DLL, не включенные в сборки, на которые ссылается манифест, загружаются традиционным способом. Поэтому унаследованные приложения связываются с версией в WindowsSystem32, а новые приложения с поддержкой тем могут ссылаться на новую версию в своих манифестах.

Чтобы увидеть, какой эффект дает манифест, указывающий системе задействовать новую библиотеку стандартных элементов управления в Windows XP, запустите User State Migration Wizard (WindowsSystem32UsmtMigwiz.exe) с файлом манифеста и без него.

1. Запустите этот мастер и обратите внимание на темы Windows XP на кнопках в мастере.

2. Откройте файл манифеста в Notepad и найдите упоминание 6-й версии библиотеки стандартных элементов управления.

3. Переименуйте Migwiz.exe.manifest в Migwiz.exe.manifest.bak.

4. Вновь запустите мастер и обратите внимание на кнопки без тем.

5. Восстановите исходное имя файла манифеста.

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

Внутреннее устройство потоков

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

Структуры данных

Ha уровне операционной системы поток представляется блоком потока, принадлежащим исполнительной системе (ETHREAD). Структура этого блока показана на рис. 6–7. Блок ETHREAD и все структуры данных, на которые он ссылается, существуют в системном адресном пространстве, кроме блока переменных окружения потока (thread environment block, TEB) — он размещается в адресном пространстве процесса. Помимо этого, процесс подсистемы Windows (Csrss) поддерживает параллельную структуру для каждого потока, созданного в Windows-процессе. Часть подсистемы Windows, работающая в режиме ядра (Win32k.sys), также поддерживает для каждого потока, вызывавшего USER- или GDI-функцию, структуру W32THREAD, на которую указывает блок ETHREAD.

Поля блока потока, показанные на рис. 6–7, в большинстве своем не требуют дополнительных пояснений. Первое поле — это блок потока ядра (KTHREAD). За ним следуют идентификационные данные потока и процесса (включая указатель на процесс — владелец данного потока, что обеспечивает доступ к информации о его окружении), затем информация о защите в виде указателя на маркер доступа и сведения, необходимые для олицетворения (подмены одного процесса другим), а также поля, связанные с сообщениями LPC и незавершенными запросами на ввод-вывод. B таблице 6–8 даны ссылки на другие части книги, где некоторые из наиболее важных полей описываются подробнее. Чтобы получить более детальные сведения о внутренней структуре блока ETHREAD, используйте команду dt отладчика ядра.

Давайте повнимательнее присмотримся к двум ключевым структурам потока, упомянутым выше, — к блокам KTHREAD и TEB. Первый содержит информацию, нужную ядру Windows для планирования потоков и их синхронизации с другими потоками. Схема блока KTHREAD показана на рис. 6–8.

Ключевые поля блока KTHREAD кратко рассмотрены в таблице 6–9.

Таблица 6–9. Ключевые поля блока KTHREAD

ЭКСПЕРИМЕНТ: просмотр структур ETHREAD и KTHREAD

Структуры ETHREAD и KTHREAD можно просмотреть с помощью команды dt отладчика ядра. B следующем выводе показан формат ETHREAD:

Для просмотра KTHREAD предназначена аналогичная команда:

ЭКСПЕРИМЕНТ: использование команды !thread отладчика ядра

Команда !thread отладчика ядра выдает дамп подмножества информации из структур данных потока. Отладчик ядра выводит ряд важных данных, не показываемых любыми другими утилитами: адреса внутренних структур, детальные сведения о приоритетах, данные стека, список незавершенных запросов на ввод-вывод и список ожидаемых объектов для тех потоков, которые находятся в состоянии ожидания.

Чтобы получить информацию о потоке, используйте либо команду !process (которая выводит все блоки потоков после блока процесса), либо команду !thread (которая сообщает сведения только об указанном потоке). Ниже дан пример информации о потоке с пояснением ее важнейших полей.

Адрес Идентификатор ETHREAD потока Адрес TEB

ЭКСПЕРИМЕНТ: просмотр информации о потоке

Утилита Tlist из Windows Debugging Tools позволяет получить подробную информацию о процессе, пример которой приведен ниже. Заметьте, что в списке потоков указывается «Win32StartAddress». Это адрес, передаваемый функции CreateThread приложением. Остальные утилиты, кроме Process Explorer, показывающие стартовый адрес потока, выводят его истинный стартовый адрес, а не стартовый адрес, заданный приложением.

B отличие от других структур данных, описываемых в этом разделе, только блок TEB, показанный на рис. 6–9, присутствует в адресном пространстве процесса, а не системы. B TEB хранится контекстная информация загрузчика образов и различных Windows DLL. Поскольку эти компоненты выполняются в пользовательском режиме, им нужны структуры данных, доступные для записи из этого режима. Вот почему TEB размещается в адресном пространстве процесса, а не системы, где он был бы доступен для записи только из режима ядра. Адрес TEB можно найти с помощью команды !thread отладчика ядра.

ЭКСПЕРИМЕНТ: исследуем TEB

Вы можете получить дамп структуры TEB, используя команду !teb отладчика ядра. Ee вывод выглядит так:

Переменные ядра

Как и в случае процессов, ряд переменных ядра Windows контролирует выполнение потоков. Список таких переменных, связанных с потоками, приводится в таблице 6-10.

Таблица 6-10. Переменные ядра, относящиеся к потокам

Счетчики производительности

Большая часть важной информации в структурах данных потоков экспортируется в виде счетчиков производительности, перечисленных в таблице 6-11. Даже используя только оснастку Performance, вы можете получить довольно много сведений о внутреннем устройстве потоков.

Сопутствующие функции

B таблице 6-12 перечислены Windows-функции, позволяющие создавать потоки и манипулировать ими. Здесь не показаны функции, связанные с планированием и управлением приоритетами потоков, — они описываются в разделе «Планирование потоков» далее в этой главе.

Рождение потока

Жизненный цикл потока начинается при его создании программой. Запрос на его создание в конечном счете поступает исполнительной системе Windows, где диспетчер процессов выделяет память для объекта «поток» и вызывает ядро для инициализации блока потока ядра. Ниже перечислены основные этапы создания потока Windows-функцией CreateThread (которая находится в Kernel32.dll).

1. CreateThread создает стек пользовательского режима в адресном пространстве процесса.

2. CreateThread инициализирует аппаратный контекст потока, специфичный для конкретной архитектуры процессора. (Подробнее о блоке контекста потока см. раздел справочной документации Windows API по структуре CONTEXT.)

3. Для создания объекта «поток» исполнительной системы вызывается Nt-CreateThread. Он создается в приостановленном состоянии. Описание операций, выполняемых NtCreateThread, см. в разделе «Что делает функция CreateProcess» (этапы 3 и 6) ранее в этой главе.

4. CreateThread уведомляет подсистему Windows о создании нового потока, и та выполняет некоторые подготовительные операции.

5. Вызвавшему коду возвращаются описатель и идентификатор потока (сгенерированный на этапе 3).

6. Выполнение потока возобновляется, и ему может быть выделено процессорное время, если только он не был создан с флагом CREATE_SUSPENDED. Перед вызовом по пользовательскому стартовому адресу поток выполняет операции, описанные в разделе «Этап 3: создание первичного потока, его стека и контекста» ранее в этой главе.

Наблюдение за активностью потоков

He только оснастка Performance, но и другие утилиты (таблица 6-13) позволяют получать сведения о состоянии потоков в Windows. (Утилиты, показывающие информацию о планировании потоков, перечисляются в разделе «Планирование потоков» далее в этой главе.)

ПРИМЕЧАНИЕ Чтобы получить информацию о потоке с помощью Tlist, введите tlistxxx, где xxx — имя образа процесса или заголовок окна (можно использовать символы подстановки).

Process Explorer позволяет наблюдать за активностью потоков в процессе. Это особенно важно, когда вы пытаетесь понять, почему процесс зависает или запускается какой-то процесс, служащий хостом для множества сервисов (например, Svchost.exe, Dllhost.exe, Inetinfo.exe или System).

Для просмотра потоков в процессе выберите этот процесс и откройте окно его свойств двойным щелчком. Потом перейдите на вкладку Threads. Ha этой вкладке отображается список потоков в процессе. Для каждого потока показывается процентная доля использованного процессорного времени (с учетом заданного интервала обновления), число переключений контекста для данного потока и его стартовый адрес. Поддерживается сортировка по любому из этих трех столбцов.

Новые потоки выделяются зеленым, а существующие — красным. (Длительность подсветки настраивается в Options.) Это помогает обнаруживать создание лишних потоков в процессе. (Как правило, потоки должны создаваться при запуске процесса, а не при каждой обработке какого-либо запроса внутри процесса.)

Когда вы поочередно выбираете потоки в списке, Process Explorer отображает их идентификаторы, время запуска, состояние, счетчики использования процессорного времени, число переключений контекстов, а также базовый и текущий приоритеты. Кнопка KiIl позволяет принудительно завершать индивидуальные потоки, но пользоваться ею следует с крайней осторожностью.

Читайте также

Процессы и потоки Windows

Процессы и потоки Windows
Внутри каждого процесса могут выполняться одна или несколько потоков, и именно поток является базовой единицей выполнения в Windows. Выполнение потоков планируется системой на основе обычных факторов: наличие таких ресурсов, как CPU и физическая

Процессы и потоки

Процессы и потоки
В этой главе представлено описание процессов и потоков в QNX/ Neutrino, диспетчеризации, системы приоритетов, и дано понятие о реальном времени. Вы узнаете о состояниях потоков и алгоритмах диспетчеризации, которые применяются в QNX/ Neutrino, а также изучите

Процессы и потоки

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

2. Процессы и потоки

2. Процессы и потоки
При внимательном чтении технической документации [8] и литературы по ОС QNX [1] отчетливо бросается в глаза, что тонкие детали создания и функционирования процессов и потоков описаны крайне поверхностно и на весьма некачественном уровне. Возможно, это

Процессы, задачи, задания, группы активизации и потоки

Процессы, задачи, задания, группы активизации и потоки
Как уже упоминалось, первоначально в AS/400 было определено три уровня работы. Самый низкий уровень, под MI, — задача. Процесс «живет» на уровне MI и построен на структуре задач SLIC. Поверх модели процессов MI OS/400 в качестве

1.2. Процессы, потоки и общий доступ к информации

1.2. Процессы, потоки и общий доступ к информации
В традиционной модели программирования Unix в системе могут одновременно выполняться несколько процессов, каждому из которых выделяется собственное адресное пространство. Это иллюстрирует рис. 1.1. 

Рис. 1.1. Совместное

ГЛABA 1  Концепции и инструменты

ГЛABA 1  Концепции и инструменты
B этой главе мы познакомим вас с основными концепциями и терминами операционной системы Microsoft Windows, которые будут использоваться в последующих главах, в том числе с Windows API, процессами, потоками, виртуальной памятью, режимом ядра и

ГЛABA 2  Архитектура системы

ГЛABA 2  Архитектура системы
Теперь, познакомившись с необходимыми терминами, понятиями и инструментами, мы можем рассмотреть задачи, которые ставились при разработке операционной системы Microsoft Windows. B этой главе описывается общая архитектура системы: ключевые компоненты,

ГЛABA 3  Системные механизмы

ГЛABA 3  Системные механизмы
B Microsoft Windows существует несколько базовых механизмов, которыми пользуются компоненты режима ядра: исполнительная система (executive), ядро и драйверы устройств. B этой главе описываются следующие системные механизмы (а также способы их

ГЛABA 4  Механизмы управления

ГЛABA 4  Механизмы управления
B этой главе описываются три фундаментальных механизма Microsoft Windows, критически важных для управления системой и ее конфигурирования:• реестр;• сервисы;• Windows Management Instrumentation (Инструментарий управления Windows).РеестрРеестр играет ключевую роль в

ГЛABA 8  Защита

ГЛABA 8  Защита
Защита конфиденциальных данных от несанкционированного доступа очень важна в любой среде, где множество пользователей обращается к одним и тем же физическим или сетевым ресурсам. У операционной системы, как и у отдельных пользователей, должна быть

ГЛABA 11  Диспетчер кэша

ГЛABA 11  Диспетчер кэша
Диспетчер кэша (cache manager) — это набор функций режима ядра и системных потоков, во взаимодействии с диспетчером памяти обеспечивающих кэширование данных для всех драйверов файловых систем Windows (как локальных, так и сетевых). B этой главе мы поясним, как

ГЛABA 7 Управление памятью

ГЛABA 7 Управление памятью
B этой главе вы узнаете, как реализована виртуальная память в Microsoft Windows и как осуществляется управление той частью виртуальной памяти, которая находится в физической. Мы также опишем внутреннюю структуру диспетчера памяти и его компоненты, в том

ГЛABA 12  Файловые системы

ГЛABA 12  Файловые системы
B начале этой главы мы даем обзор файловых систем, поддерживаемых Windows, а также описываем типы драйверов файловых систем и принципы их работы, в том числе способы взаимодействия с другими компонентами операционной системы, например с диспетчерами

ГЛABA 13 Поддержка сетей

ГЛABA 13 Поддержка сетей
Windows создавалась с учетом необходимости работы в сети, поэтому в операционную систему включена всесторонняя поддержка сетей, интегрированная с подсистемой ввода-вывода и Windows API. K четырем базовым типам сетевого программного обеспечения относятся

Что такое процессМногим пользователям Windows приходилось слышать о процессах, но не все знают что такое «процессы», для чего они нужны и нужно ли на них вообще обращать внимание. Именно поэтому я запланировал серию заметок, в которых немного расскажу о процессах Windows.

Можно сказать, что процесс — это выполняемая на компьютере программа, но тут нужно кое что прояснить. Дело в том, что программа и процесс — это не одно и тоже. Программа представляет собой некоторый код (набор команд и инструкций), который находится на компьютере в виде файлов. А вот процесс — это некоторый набор ресурсов и данных, которые используются при выполнении программы. То есть упрощенно можно сказать, что процесс — это выполняющаяся программа со всеми необходимыми для ее выполнения ресурсами.

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

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

Диспетчер задач

Далее необходимо перейти на вкладку «Процессы».

Процесы Windows

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

Windows — это операционная система (ключевое слово здесь — «система»), то есть можно сказать, что это пакет программ, предназначенных для управления компьютером. Системные программы в Windows называют службами и каждая из них решает определенные узконаправленные задачи.

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

Обычно по умолчанию Windows настроена некоторым универсальным (по мнению разработчиков) образом и вполне вероятна ситуация, что запускаемые со стартом Windows процессы вы никогда не будете использовать, а значит они будут просто висеть «мертвым грузом», перетягивая на себя некоторые ресурсы компьютера.

Список запущенных процессов, который вы увидите открыв Диспетчер задач, будет характерен только для вашего компьютера, ведь как вы понимаете, количество и набор процессов зависит от установленных и запущенных на вашем компьютере программ, а также от редакции операционной системы. И тут речь идет не только о версии Windows (например, XP, Vista, 7 или 8), а и о редакции — так у Windows 7 Домашняя набор запущенных процессов будет отличаться от Windows 7 Максимальная и дело тут в том, что эти операционные системы предназначены для разных задач, а значит и список запускаемых со стартом Windows системных служб будет у них отличаться.

Более подробно о некоторых службах и процессах я расскажу в следующих заметках.

Понравилась статья? Поделить с друзьями:
  • Какие папки можно почистить в папке windows
  • Какие папки можно почистить в windows 10 на диске c
  • Какие папки можно очистить на диске с в windows 10
  • Какие папки можно очистить в папке windows
  • Какие папки лишние в папке windows