5. Вычислительный процесс. Жизненный цикл и состояния процессов, уровни выполнения. Структура вычислительного процесса, образ процесса, адресное пространство.
Процесс состоит из:
- исполняемой программы (код и данные);
- закрытого ‘’адресного пространства’ (address space’‘’), т.е. набора адресов * виртуальной памяти, который процесс может использовать;
- системных ресурсов, выделяемых ОС процессу во время выполнения программы (семафоров, файлов и т.д.);
- по крайней мере, одного потока управления’ (thread of execution’‘’). Поток – это сущность внутри процесса, которую ядро направляет на исполнение. Без него программа процесса не может выполняться.
Процесс в UNIX создается системным вызовом fork(2).
Процесс, сделавший вызов fork(2), называется родительским, а вновь созданный - дочерним. Новый процесс является точной копией породившего его процесса. Каждый процесс имеет одного родителя, но может иметь несколько потомков. Для запуска задачи, то есть загрузки новой программы, процесс должен сделать вызов exec(3). При этом новый процесс не порождается, а исполняемый код нового процесса полностью замещается кодом запускаемой программы. Тем не менее сохраняются значения переменных окружения, назначение стандартных потоков ввода/вывода и ошибок, а также приоритет процесса. В UNIX запуск на выполнение новой программы часто связан с порождением нового процесса. Таким образом, процесс сначала выполняет fork, порождая дочерний процесс, который затем выполняет exec, полностью замещая родительский процесс. Такая процедура запуска называется forkand-exec. Бывают ситуации, когда достаточно одного вызова fork без последующего exec. В этом случае исполняемый код родительского и дочернего процессов должен содержать логическое ветвление для родительского и дочернего процессов. (fork возвращает PID порожденного процесса в родительский и ноль - в дочерний.) Все процессы создаются через вызов fork. Запуск осуществляется либо по fork-and-exec, либо с помощью exec. Прародителем всех процессов является init или распределитель процессов.
Состояния процессов в UNIX
- Выполняющийся пользовательский - Выполняющийся в пользовательском режиме
- Выполняющийся ядра - Выполняющийся в режиме ядра
- Готовый к выполнению, загруженный - Готов к выполнению, как только ядро решит передать ему управление
- Спящий, загруженный - Не может выполняться, пока не произойдет некоторое событие; процесс находится в основной памяти (блокированное состояние)
- Готовый к выполнению, выгруженный - Процесс готов к выполнению, но прежде чем ядро сможет спланировать его запуск, процесс свопинга должен загрузить этот процесс в основную память
- Спящий, выгруженный - Процесс ожидает некоторого события; он выгружен из основной памяти (блокированное состояние)
- Вытесненный - В момент переключения процессора из режима ядра в пользовательский режим ядро решает передать управление другому процессу
- Созданный - Процесс только что создан и еще не готов к выполнению
- Зомби - Самого процесса больше не существует, но записи о нем остались с тем, чтобы ими мог воспользоваться родительский процесс
Соответственно и образ процесса состоит из двух частей: данных режима ядра и режима задачи. Образ процесса в режиме задачи состоит из сегмен та кода, данных, стека, библиотек и других структур данных, к которым он может получить непосредственный доступ. Образ процесса в режиме ядра состоит из структур данных, недоступных процессу в режиме задачи, которые используются ядром для управления процессом. Сюда относятся данные, диктуемые аппаратным уровнем, например состояния регистров, таблицы для отображения памяти и т. д., а также структуры данных, необходимые ядру для обслуживания процесса. Вообще говоря, в режиме ядра процесс имеет доступ к любой области памяти.
Каждому процессу выделяется “плоское” 32- или 64-битовое адресное пространство. Термин “плоское” обозначает, что адресное пространство состоит из одного диапазона адресов (например, 32-разрядное адресное пространство занимает диапазон адресов от 0 до 429496729). Важной частью адресного пространства являются интервалы адресов памяти, к которым процесс имеет право доступа, как, например, 08048000–0804c000. Такие интервалы разрешенных адресов называются областями памяти (memory area). С помощью ядра процесс может динамически добавлять и удалять области памяти своего адресного пространства.