В Windows и созданием процесса и запуском в нем нужной программы управляет функция CreateProcess. Родительский и
дочерний процессы имеют собственные адресные пространства, различные изначально. Процессы в Windows идентифици-
руются как дескрипторами, так и идентификаторами процессов. GetCurrentProcess и GetCurrentProcessId возвращают де-
скриптор и идентификатор соответственно. Завершается процесс функцией ExitProcess. Ожидание завершения процесса
или группы процессов выполняется функциями WaitForSingleObject и WaitForMultipleObject. Во втором случае происхо-
дит ожидание либо одного из указанных объектов либо всех. Выполнение дочернего процесса не зависит от родительского.
Функция CreateProcess выполняет следующие действия:
- открывается исполняемый файл
- если файл не является Windows-приложением, ищется образ поддержки (программа) для запуска этого приложения
- создается и инициализируется объект процесса исполнительной системы ОС
- создается первичный поток – стек, контекст и объект потока исполнительной системы
- подсистема Windows получает сообщение о создании нового процесса и потока
- начинается выполнение первичного потока
- в контексте нового процесса и потока инициализируется адресное пространство и начинается выполнение программы
Процессы и потоки.
Процесс можно рассматривать как способ объединения используемых ресурсов в одну группу. Процесс имеет свое вирту-
альное адресное пространство, ему назначаются ресурсы – файлы, окна, семафоры и т.д. Это позволяет защитить процессы
друг от друга. ОС считает процессы совершенно несвязанными между собой. С другой стороны процесс можно рассматри-
вать как поток исполняемых команд. У потока или нити (thread) есть счетчик команд, отслеживающий последовательность
операций, регистры, хранящие текущие значения, стек, содержащий протокол выполнения. Концепция потоков добавляет к
модели процесса возможность одновременного выполнения в одной и той же среде процесса нескольких в достаточной сте-
пени независимых программ. Для них ОС не требуется организовывать полноценную виртуальную машину. Они не имеют
собственных ресурсов, пользуясь общими для процесса ресурсами. Единственный ресурс, который им необходим – это про-
цессор. В однопроцессорной системе потоки разделяют между собой процессорное время точно так же, как и процессы, в
мультипроцессорной могут выполняться одновременно.
Многопоточность обеспечивает параллельное выполнение нескольких видов
операций в одной программе. Особо эффективно выполнение многопоточных
приложений на распределенных системах. Т.о., процесс предполагает, что при
диспетчеризации требуется учитывать все ресурсы, закрепленные за ним. При
переключении между потоками достаточно изменять только контекст задачи, не
затрагивая всех остальных ресурсов. Каждый процесс всегда имеет как минимум
один поток. Каждый поток выполняется строго последовательно. Потоки, как и
процессы могут порождать потоки-потомки. Аналогично процессам, поток может
находиться в одном из активных состояний. Пока один поток заблокирован, другой
может выполняться. Поскольку потоки одного процесса выполняются в одном и том
же виртуальном адресном пространстве, между ними легче организовать тесное
взаимодействие, в отличие от процессов, которым необходимы специальные
механизмы обмена сообщениями и данными. Для потоков не существует прерываний
по таймеру, позволяющему установить режим разделения времени, поэтому
существует запрос, позволяющий потоку самостоятельно передать управление
другому.
Возможны два основных варианта реализации потоков – на уровне пользователя и на
уровне ядра. В первом случае у каждого процесса имеется своя собственная таблица
потоков, в которой хранится информация, необходимая для переключения потока в состояние выполнения. Когда поток на
уровне пользователя завершает на время свою работу, процедуре передачи управления нет необходимости использовать
системные вызовы на уровне ядра, поскольку вся информация о потоках находится внутри процесса-хозяина. Соответствен-
но, процедура может сама сохранить информацию в таблице потоков, более того, даже вызвать планировщик потоков для
выбора следующего. Соответственно не требуется прерывание, переключение контекста, сохранение кэша и т.д., что дает
значительное ускорение. Потоки на уровне пользователя позволяют каждому процессу иметь собственный алгоритм плани-
рования потоков. Однако в общем случае, при блокировке одного потока блокируется весь процесс. Ядру ничего не извест-
но о том, что приложение многопоточное, поэтому вся синхронизация при доступе к общим переменным из разных потоков
должна быть выполнена на уровне пользователя. В Windows такие потоки называются облегченными.
При реализации на уровне ядра, таблица потоков единая для всех процессов. Ядро в общем случае может при блокировании
потока выбрать новый, не принадлежащий текущему процессу. В терминологии UNIX такие потоки часто называют “легко-
весными процессами”. (LWP, lightweight process). В отличие от пользовательских потоков, при блокировке одного LWP ос-
тальные продолжают работать. Поскольку все потоки LWP планируются на выполнение ядром независимо друг от друга, но
в отличие от полновесных процессов, разделяют общее адресное пространство, при доступе к переменным, используемым
несколькими LWP, требуется применение специальных механизмов синхронизации на уровне ядра. Все запросы, которые
могут блокировать поток, реализуются как системные, что увеличивает временные издержки. Чтобы их снизить некоторые
системы после завершения потока не уничтожают его структуры, только помечая, как неработающий. При запросе на созда-
ние нового потока используются уже готовые структуры. В Windows именно потоки, а не процессы являются объектами
диспетчеризации. Т.е. планировщик выбирает из очереди готовый поток, а не процесс.