Родительский процесс, будь то первоначальный родитель или init
Между механизмами, которые ожидают завершения потомков, и сигнальными механизмами, которые мы еще не обсуждали, есть значительное взаимодействие. Что из них описать вначале представляет собой нечто вроде проблемы курицы и яйца; мы решили сначала поговорить сначала о механизмах ожидания порожденного процесса, а глава 10 «Сигналы» дает полный рассказ о сигналах.
Пока достаточно понять, что сигнал является способом уведомления процесса о том, что произошло некоторое событие. Процессы могут генерировать сигналы, которые посылаются самим себе, или сигналы могут посылаться извне другими процессами или пользователем за терминалом. Например, CTRL-C посылает сигнал «прерывания», a CTRL-Z посылает сигнал управления работой «стоп».
По умолчанию, многие сигналы, такие, как сигнал прерывания, заставляют получающий процесс закончиться. Другие, такие, как сигналы управления работами, вызывают изменение его состояния. Механизмы ожидания порожденного процесса могут определить, претерпел ли процесс сигнал завершения, и если да, какой это был сигнал. То же верно и для остановки процесса и, на некоторых системах возобновления процесса.
9.1.6.1. Использование функций POSIX: wait()
waitpid()
Первоначальным системным вызовом V7 был wait()
waitpid()
. Объявления функций следующие:#include
#include
pid_t wait(int *status);
pid_t waitpid(pid_t pid, int *status, int options);
wait()
*status
. (Вскоре мы обсудим, как интерпретировать *status
.) Возвращаемое значение является PID завершившегося процесса или -1, если возникла ошибка.Если порожденных процессов нет, wait()
errno
, установленным в ECHILD
(отсутствует порожденный процесс). В противном случае, функция ждет завершения первого порожденного процесса или поступления сигнала.Функция waitpid()
pid_t pid
Значение указывает, завершения какого порожденного процесса ждать как по-настоящему pid
pid
следующий:pid < -1
pid
.pid = -1
wait()
.pid = 0
pid > 0
pid
.int *status
То же, что и для wait()
определяет различные макросы, которые интерпретируют значение в *status
, которые мы вскоре опишемint options
Этот параметр должен быть равен либо 0, либо побитовым ИЛИ одного или более из следующих флагов:
WNOHANG
Если ни один порожденный процесс не завершился, вернуться немедленно. Таким способом можно периодически проверять, не закончился ли какой- нибудь порожденный процесс. (Такая периодическая проверка известна как
WUNTRACED
Вернуть сведения о порожденном процессе, который остановился, но еще не завершился. (Например, для управления работой.)
WCONTINUED
(XSI.) Вернуть сведения о порожденном процессе, который продолжился, если его статус не сообщался с момента изменения. Это также для управления работой. Этот флаг является расширением XSI и не доступен под GNU/Linux.
С заполненным значением *status
WIFEXITED(status)
Этот макрос не равен нулю (true), если процесс завершился (в противоположность изменению состояния).
WEXITSTATUS(status)
Этот макрос дает статус завершения; он равен восьми наименее значимым битам значения, переданного exit()
main()
. Этот макрос следует использовать лишь если WIFEXIDED(status)
равен true.