Жизненный цикл процесса
Категория: Управление процессами | Автор: admin | 30-09-2009, 04:11 | Просмотров: 4721

Для создания нового процесса существующий процесс клонирует самого себя с помощью системного вызова fork. Результатом является получение копии исходного процесса, имеющей лишь некоторые отличия. В частности, новому процессу присваивается новый идентификатор, и учет ресурсов ведется для него независимо от предка.

Системный вызов fork обладает уникальным свойством: он возвращает сразу два значения. В порожденном процессе эта функция возвращает 0, а в родительском — идентификатор потомка. Поскольку в остальном процессы идентичны, они должны проверять это значение, чтобы определить, в какой роли следует выступать дальше.

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

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

 

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

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

Описанный механизм работает нормально, если родительский процесс завершается позже порожденных им процессов и добросовестно выполняет системные вызовы wait для того, чтобы все процессы-зомби были уничтожены. Если же родительский процесс завершается первым, то ядро понимает, что вызова wait не последует, и переназначает все процессы-зомби программе init. Она обязана принять "осиротевшие" процессы и ликвидировать их, осуществив для каждого из этих процессов вызов wait.

Раньше программа init не всегда выполняла свои обязанности как следует и зомби оставались в системе. В последнее время, однако, подобных проблем мы не замечали.



 (голосов: 1)
Версия для печати | Комментариев: 0
Информация
Посетители, находящиеся в группе Гости, не могут оставлять комментарии в данной новости.


 
Логин
Пароль
 

 
Locations of visitors to this page