Файл: Учебнометодическое пособие Томск 2016 2 удк 004. 451(075. 8) Ббк 32. 973. 2018. 2я73 к 754 Рецензенты.pdf
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 25.10.2023
Просмотров: 300
Скачиваний: 2
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
СОДЕРЖАНИЕ
136
5 Подсистема управления процессами
Данная подсистема занимает центральное место среди подсистем ОС, выполняя различные функции по обеспечению существования процессов.
В п. 3.2 было приведено краткое определение процесса, согласно которому процесс есть одно выполнение последовательной программы. Более подробное определение:
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
Процесс – последовательная программа, располагающая
окружением, достаточным для своего выполнения.
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
Окружение программы образуют системные программы и системные структуры данных, обслуживающие данную программу. Так как эти программы и структуры данных реализуют виртуальную машину прикладной программы, то можно сказать, что процесс – последовательная программа, загруженная в свою виртуальную машину.
5.1 Состояния процесса
Являясь важнейшим объектом управления со стороны ОС, процесс мо- жет находиться в состояниях, изображенных на рисунке 5.1. При этом дуги обозначают переходы между состояниями, а на дугах проставлены причины переходов. Эти причины бывают двух типов – системные вызовы, выдаваемые или процессом-отцом, или самим процессом, или события, происходящие внут- ри ядра ОС и приводящие к запуску каких-то подпрограмм ядра.
Создание процесса выполняет процесс-отец. Например, если вы запускае- те какую-то программу из командной строки UNIX, то процессом-отцом явля- ется тот процесс-shell, в диалоге с которым вы запускаете данную програм- му. Для создания нового процесса процесс-отец использует системный вызов:
СОЗДАТЬ_ПРОЦЕСС (|| i p
), (на Си – fork), где i p
– номер нового процесса.
В результате выполнения ядром первой фазы данного системного вызова новый процесс оказывается в состоянии «Создан». Это переходное состояние: процесс уже существует, но еще не готов к запуску.
137
Рис. 5.1 – Состояния процесса
В результате второй фазы выполнения системного вызова процесс оказы- вается в состоянии «Готов». В этом состоянии он обладает всеми ресурсами, за исключением ЦП. В результате выполнения подпрограммы ядра, называемой
диспетчером, программа процесса начинает выполняться на ЦП.
138
Если на процессоре выполняются команды самой прикладной програм- мы, то процесс находится в состоянии «Задача». Этому состоянию соответству- ет наименее приоритетное состояние аппаратуры ЦП.
Если очередная выполняемая команда программы есть или команда, при- ведшая к исключению (исключение – внутреннее аппаратное прерывание), или команда системного вызова, то на ЦП начинает исполняться соответствующая подпрограмма ядра ОС. (Напомним, что команда системного вызова представ- ляет собой или команду программного прерывания int, или команду перехода jmp
, каждая из которых делает переход на точку входа в ядро ОС.) В обоих указанных случаях инициирование подпрограммы ядра ОС производится в ин- тересах процесса и более того, это выполнение считается его частью. При вы- полнении подпрограмм ядра аппаратура ЦП находится в самом приоритетном состоянии, а сам процесс в состоянии «Ядро».
Перечисленные выше команды перехода из состояния «Задача» в состоя- ние «Ядро» предназначены для получения помощи прикладной программой со стороны ОС. Очень часто эта помощь не может быть оказана достаточно быстро, так как приходится ожидать завершения операции ввода-вывода, или ожидать освобождения ресурса, требуемого для продолжения программы. Что- бы в этом случае процесс не занимал бесполезно ЦП, процесс переводится в состояние «Сон» с помощью внутренней подпрограммы ядра sleep. Когда освобождается ресурс, которого ожидает «спящий» процесс, или завершается ожидаемая им операция ввода-вывода, выполняется внутренняя подпрограмма ядра – wakeup. Она переводит процесс в состояние «Готов», из которого он будет переведен впоследствии диспетчером в состояние «Ядро».
При завершении системного вызова процесс переходит из состояния
«Ядро» в состояние «Задача», если на данный момент нет более приоритетного процесса, находящегося в состоянии «Готов». При наличии такого процесса выполняемый процесс переводится диспетчером в состояние «Готов». Пере- ключение ЦП с одного процесса на другой производится диспетчером путем замены на ЦП аппаратного контекста одного процесса на аппаратный контекст другого процесса.
Причиной любого перехода процесса из состояния «Ядро» в состояния
«Задача», «Готов», «Сон» является сам процесс. Никакой другой процесс не может вывести процесс из состояния «Ядро». Исключениями являются об- работчики наиболее важных аппаратных прерываний, выполнение которых не может быть отложено даже на короткий срок. После завершения обработки
139 прерывания выполнение процесса продолжится опять в состоянии «Ядро». Бо- лее того, во время выполнения этих обработчиков прерванный процесс не вы- ходит из состояния «Ядро», так как обработчики прерываний выполняются в его аппаратном контексте.
Напомним, что последовательное разделение ядра процессами произво- дится с целью обеспечить целостность системных данных ядра. Одним из след- ствий данного принципа является то, что замена процесса, выполняемого на
ЦП, происходит чаще всего при переходе процесса из состояния «Ядро» в со- стояние «Задача». Другим следствием является необходимость сокращения времени пребывания процесса в состоянии «Ядро». Для этого требуется опти- мизировать выполнение системных функций по времени выполнения.
Переходы между состояниями «Готов», «Задача», «Ядро» и «Сон» будут продолжаться до тех пор, пока не будет выполнена подпрограмма ядра exit.
Она может быть вызвана как в результате получения процессом какого-то сиг- нала, например SIGKILL, требующего завершения процесса, так и в результате выдачи самой прикладной программой процесса системного вызова:
ЗАВЕРШИТЬ_ПРОЦЕСС (||),
(на Си – exit).
В результате выполнения подпрограммы ядра exit процесс переходит в состояние «Зомби». В этом состоянии процесс фактически уже не существует.
Все занимавшиеся им ресурсы освобождены, а его дочерние процессы стано- вятся дочерними процессами процесса init, являющегося «прародителем» всех порождаемых процессов UNIX. Единственный неосвобождаемый ресурс – одна строка в системной таблице процессов proc, содержащая код завершения процесса и информацию о затратах времени ЦП на его выполнение.
Существование процесса прекратится полностью в результате выдачи процессом-отцом системного вызова:
ИНФОРМАЦИЯ_ЗАВЕРШЕНИЯ (|| i p
, k), (на Си – wait), где i p
– номер завершенного дочернего процесса; k – код завершения процесса.
Для выполнения этого системного вызова будет инициирована подпро- грамма ядра wait, которая выдаст номер завершенного дочернего процесса, его код завершения и уничтожит соответствующую строку в таблице proc. Ес- ли на момент выдачи этого системного вызова дочерний процесс еще не завер- шился, процесс-отец переходит в состояние «Сон», ожидая указанного собы- тия.
140
В некоторых UNIX-системах существует дополнительное состояние про- цесса – «Останов». В это состояние процесс переходит из состояния «Задача» или «Готов» в результате поступления сигнала SIGSTOP, выданного другим процессом, или сигналаSIGTSTP, выдаваемого в результате нажатия комбина- ции клавиш
«Готов» производится в результате поступления сигналаSIGCONT.
1 ... 9 10 11 12 13 14 15 16 ... 23
5.2 Создание процесса
В результате создания процесса должно быть создано окружение про- граммы, состоящее из переменных окружения процесса и следующих структур данных ядра ОС:
1) управляющая структура proc;
2) управляющая структура user;
3) структуры отображения памяти.
Первые две структуры вместе образуют блок управления (дескриптор) процесса. Структура proc используется ОС для выполнения манипуляций над процессом. Структуры proc для всех существующих в системе процессов объ- единены в единую таблицу процессов системы. Каждая proc является строкой этой таблицы. Системная переменная curproc содержит номер (индекс в таб- лице) того proc, который соответствует процессу, исполняемому в данный момент времени на ЦП.
Основное содержание структуры proc:
1) системное имя (номер) процесса;
2) номер процесса-отца;
3) номер сеанса, к которому принадлежит процесс;
4) номер группы процессов, к которой принадлежит процесс;
5) системное имя (номер) пользователя – владельца процесса;
6) информация о затратах времени ЦП на выполнение процесса (отдель- но – в режиме «Задача» и в режиме «Ядро»);
7) сигналы, ожидающие доставки процессу;
8) текущее состояние процесса;
9) текущий приоритет процесса на получение времени ЦП;
10) системное имя (номер) события, возникновения которого ожидает процесс в состоянии «Сон»;
141 11) указатель (линейный адрес) на структуру user;
12) указатель на таблицу LTD (рассматривается в п. 6.2);
13) код завершения процесса, предназначенный для передачи в процесс- отец.
В отличие от структуры proc, которая используется ядром ОС, в основ- ном, во время выполнения других процессов, системная структура userис- пользуется самим процессом (в режиме ядра). Эта структура содержит:
1) указатель на область памяти, содержащуюзаголовок исполняемого
файла.Это – служебная информация, которая предваряет код и дан- ные прикладной программы и которая может использоваться как при создании процесса, так и впоследствии им самим (аналог PSP в MS-
DOS);
2) указатель насистемный стек – область памяти фиксированного раз- мера, используемая в качестве стека при выполнении процесса в ре- жиме «Ядро» (у каждого процесса свой системный стек);
3) указатель наобласть памяти, содержащуюаппаратный контекст – состояние ЦП (содержимое его регистров) в момент прекращения вы- полнения данного процесса на ЦП. При возобновлении выполнения процесса содержимое данной области копируется в соответствующие регистры;
4) имя начального каталога пользователя. Это имя переписывается из файла /etc/passwd;
5) имя текущего каталога пользователя. Относительно этого имени про- грамма процесса может задавать относительные имена файлов;
6) диспозиция сигналов. Назначение данного поля будет рассмотрено в следующем разделе.
Кроме системных структур (proc,user и отображения памяти), доступ к которым процесс имеет только в состоянии «Ядро», при создании процесса инициализируются (заполняются) переменные окружения, наследуемые про- цессом от процесса-отца (см. пп. 2.5.4).
Особенностью создания нового процесса в UNIX является то, что новый процесс, полученный в результате выполнения ядром системного вызоваСО-
ЗДАТЬ_ПРОЦЕСС, является почти полной копией своего процесса-отца. При этом он имеет такую же программу, переменные окружения, структуры proc и user. Основное различие между процессами в том, что новый процесс имеет
142 другое имя (номер). Таким образом, результатом выполнения данного систем- ного вызова является одновременное существование в данный момент двух процессов, выполняющих одну и ту же программу, причем в одной и той же ее точке – указатель команды EIP содержит адрес команды, которая следует в программе за командой, реализующей системный вызовСОЗДАТЬ_ПРОЦЕСС.
Дальнейшее выполнение одной и той же программы процессом-отцом и дочерним процессом различно по той причине, что различается значение па- раметраi p
, возвращаемого системным вызовом в эти два процесса. При возвра- те в дочерний процесс этот параметр содержит не номер нового процесса, а число 0. Поэтому после команды системного вызоваСОЗДАТЬ_ПРОЦЕСС
(|| i p
) программа должна содержать оператор условного перехода, выпол- няющий ветвление программы в зависимости от значения параметра i p
Далее дочерний процесс может продолжать выполнение копии програм- мы процесса-отца или потребовать от ядра ОС выполнения своей собственной программы. Для этого ему достаточно передать ядру системный вызов:
ЗАГРУЗИТЬ_ПРОГРАММУ (I
F
||), (на Си – exec), где I
F
– имя файла, содержащего запускаемую программу. В качестве такого файла может быть задан не только исполняемый файл, но и скрипт.
Особенностью данного системного вызова является то, что при его нор- мальном завершении управление не возвращается в ту точку прикладной про- граммы, откуда был сделан вызов, так как вместо этой программы будет загру- жена новая программа, в которую и будет передано управление.
Выполнение данного системного вызова начинается с того, что проверя- ется наличие права доступа x (выполнение) процесса по отношению к загружа- емому файлу. Этим правом может обладать или пользователь-владелец процес- са, или группа пользователей, к которой принадлежит владелец процесса, или это право присуще всем пользователям файла. При отсутствии такого права выполняется возврат из системного вызова в старую программу. Иначе – про- веряется наличие модификатора s у права доступа x. При наличии такого мо- дификатора номер пользователя-владельца в структуре proc заменяется на но- мер пользователя-владельца загружаемого файла.
Далее определяется тип загружаемого файла. В исполняемом бинарном файле для этого используются первые два байта файла, содержащие так назы- ваемое магическое число. Если файл является скриптом, то его первая строка может задавать тип требуемого shell (см. пп. 2.5.6). Если файл не является ни