Нормальное завершение процесса происходит при достижении конца функции main или при выполнении системного вызова exit
. При этом процесс устанавливает некоторый код своего завершения, который может
быть прочитан процессом-предком.
Принудительное завершение процесса в Linux извне может быть выполнено при помощи
системного вызова kill, посылающего
процессу сигнал. Подробное рассмотрение сигналов мы проведем в следующей
лабораторной работе, пока же только отметим, что гарантированно "убить"
процесс, имеющий PID = p, можно системным вызовом:
kill(p,SIGKILL)
Ожидание завершения процесса
Процесс-предок может ожидать завершения процесса-потомка (или
процессов-потомков) при помощи системных вызовов wait
или waitpid. Если процесс-потомок
еще не завершился, процесс-предок переводится таким системным вызовом в
состояние ожидания до завершения процесса-потомка (впрочем, процесс может и не
ожидать завершения потомка, а только проверить, завершился ли он). Эти
системные вызовы позволяют также процессу предку узнать код завершения потомка.
Если процесс-потомок завершает свою работу прежде процесса-предка, и процесс-предок явно не указал, что он не заинтересован в получении информации о статусе завершения процесса-потомка, то завершившийся процесс-потомок не исчезает из системы окончательно, а остается в состоянии закончил исполнение (зомби-процесс) либо до завершения процесса-предка, либо до того момента, когда предок проверит завершение потомка.
Каждый процесс-потомок при завершении работы посылает своему процессу-предку специальный сигнал SIGCHLD, на который у всех процессов по умолчанию установлена реакция "игнорировать сигнал". Наличие такого сигнала совместно с системным вызовом waitpid() позволяет организовать асинхронный сбор информации о статусе завершившихся порожденных процессов процессом-предком.