Архитектура Unix

       

. Алгоритм функции exit



Рисунок 7.14. Алгоритм функции exit

алгоритм exit входная информация: код, возвращаемый родительскому про- цессу выходная информация: отсутствует { игнорировать все сигналы; если (процесс возглавляет группу процессов, ассоцииро- ванную с операторским терминалом) { послать всем процессам, входящим в группу, сигнал о "зависании"; сбросить в ноль код группы процессов; } закрыть все открытые файлы (внутренняя модификация алго- ритма close); освободить текущий каталог (алгоритм iput); освободить области и память, ассоциированную с процессом (алгоритм freereg); создать запись с учетной информацией; прекратить существование процесса (перевести его в соот- ветствующее состояние); назначить всем процессам-потомкам в качестве родителя процесс init (1); если кто-либо из потомков прекратил существование, послать процессу init сигнал "гибель потомка"; послать сигнал "гибель потомка" родителю данного процес- са; переключить контекст; }


Наконец, ядро освобождает всю выделенную задаче память вместе с соответствующими областями (по алгоритму detachreg) и переводит процесс в состояние прекращения существования. Ядро сохраняет в таблице процессов код возврата функции exit (status), а также суммарное время исполнения процесса и его потомков в режиме ядра и режиме задачи. В разделе 7.4 при рассмотрении функции wait будет показано, каким образом процесс получает информацию о времени выполнения своих потомков. Ядро также создает в глобальном учетном файле запись, которая содержит различную статистическую информацию о выполнении процесса, такую как код идентификации пользователя, использование ресурсов центрального процессора и памяти, объем потоков ввода-вывода, связанных с процессом. Пользовательские программы могут в любой момент обратиться к учетному файлу за статистическими данными, представляющими интерес с точки зрения слежения за функционированием системы и организации расчетов с пользователями. Ядро удаляет процесс из дерева процессов, а его потомков передает процессу 1 (init). Таким образом, процесс 1 становится законным родителем всех продолжающих существование потомков завершающегося процесса. Если кто-либо из потомков прекращает существование, завершающийся процесс посылает процессу init сигнал "гибель потомка" для того, чтобы процесс начальной загрузки мог удалить запись о потомке из таблицы процессов (см. раздел 7.9); кроме того, завершающийся процесс посылает этот сигнал своему родителю. В типичной ситуации родительский процесс синхронизирует свое выполнение с завершающимся потомком с помощью системной функции wait. Прекращая существование, процесс переключает контекст и ядро может теперь выбирать для исполнения следующий процесс; ядро с этих пор уже не будет исполнять процесс, прекративший существование.

В программе, приведенной на Рисунке 7.15, процесс создает новый процесс, который печатает свой код идентификации и вызывает системную функцию pause, приостанавливаясь до получения сигнала. Процесс-родитель печатает PID своего потомка и завершается, возвращая только что выведенное значение через параметр status. Если бы вызов функции exit отсутствовал, начальная процедура сделала бы его по выходе процесса из функции main. Порожденный процесс продолжает ожидать получения сигнала, даже если его родитель уже завершился.



Содержание раздела