WAIT(2)

ИМЯ
wait, waitpid - ожидает завершения процесса

КРАТКАЯ СВОДКА
#include <sys/types.h>
#include <sys/wait.h>

pid_t wait(int *status)
pid_t waitpid(pid_t pid, int *status, int options);

ОПИСАНИЕ
Функция wait приостанавливает выполнение текущего процесса до тех пор, пока дочерний процесс не прекратит выполнение или до появления сигнала, который либо завершает текущий процесс, либо требует вызвать функцию-обработчик. Если дочерний процесс к моменту вызова функции уже завершился (так называемый "зомби"), то функция немедленно возвращается. Системные ресурсы, связанные с дочерним процессом, освобождаются. Функция waitpid приостанавливает выполнение текущего процесса до тех пор, пока дочерний процесс, указанный в параметре pid, не завершит выполнение, или пока не появится сигнал, который либо завершает текущий процесс либо требует вызвать функцию-обработчик. Если указанный дочерний процесс к моменту вызова функции уже завершился (так называемый "зомби"), то функция немедленно возвращается. Системные ресурсы, связанные с дочерним процессом, освобождаются. Параметр pid может принимать несколько значений:

< -1
    означает, что нужно ждать любого дочернего процесса, чей идентификатор группы процессов равен абсолютному значению pid.

-1  означает ожидать любого дочернего процесса; функция wait ведет себя точно так же.

0   означает ожидать любого дочернего процесса, чей идентификатор группы процессов равен таковому у текущего процесса.

> 0 означает ожидать дочернего процесса, чем идентификатор равен pid.

Значение options создается путем битовой операции ИЛИ над следующими константами:

WNOHANG
    означает вернуть управление немедленно, если ни один дочерний процесс не завершил выполнение.

WUNTRACED
    означает возвращать управление также для остановленных дочерних процессов, о чьем статусе еще не было сообщено.

Если status не равен NULL, то функции wait и waitpid сохраняют информацию о статусе в переменной, на которую указывает status. Этот статус можно исследовать с помощью нижеследующих макросов (они принимают в качестве аргумента буфер (типа int), — а не указатель на буфер!):

WIFEXITED(status)
    не равно нулю, если дочерний процесс нормально завершился.

WEXITSTATUS(status)
    возвращает восемь младших битов возвращаемого значения завершившегося дочернего процесса. Эти биты могли быть установлены в аргументе функции exit() или в аргументе оператора return в функции main(). Этот макрос можно использовать, только если WIFEXITED вернул ненулевое значение.

WIFSIGNALED(status)
    возвращает истинное значение, если дочерний процесс завершился из-за неперехваченного сигнала.

WTERMSIG(status)
    возвращает номер сигнала, который привел к завершению дочернего процесса. Этот макрос можно использовать только если WIFSIGNALED вернул ненулевое значение.

WIFSTOPPED(status)
    возвращает истинное значение, если дочерний процесс, из-за которого функция вернула управление, в настоящий момент остановлен; это возможно только если использовался флаг WUNTRACED.

WSTOPSIG(status)
    возвращает номер сигнала, из-за которого дочерний процесс был остановлен. Этот макрос можно использовать только если WIFSTOPPED вернул ненулевое значение.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
Идентификатор дочернего процесса, который завершил выполнение, -1 в случае ошибки или нуль, если использовался WNOHANG, но ни один дочерний процесс еще не завершил выполнение (в этом случае errno устанавливается должным образом).

ОШИБКИ

ECHILD
    процесс, указанный в pid, не существует или не является дочерним процессом текущего процесса. (Это может случиться и для собственного дочернего процесса, если обработчик сигнала SIGCHLD установлен в SIG_IGN. Смотри также главу ЗАМЕЧАНИЯ по поводу нитей.)

EINVAL
    Аргумент options неверен.

ERESTARTSYS
    Использовался флаг WNOHANG, и был пойман неблокированный сигнал или SIGCHLD. Эта ошибка возвращается системным вызовом. Библиотечные функции не могу вернуть ERESTARTSYS, но должны вернуть EINTR.

ЗАМЕЧАНИЯ
Стандарт Single Unix Specification описывает флаг SA_NOCLDWAIT (не реализован под Linux), такой, что если он установлен, или обработчик сигнала SIGCHLD установлен в SIG_IGN (что, кстати, не разрешено стандартном POSIX), то завершившиеся дочерние процессы не становятся зомби, а вызов wait() или waitpid() блокируется, пока все дочерние процессы не завершатся, а затем возвращает код ошибки, устанавливая errno в ECHILD.

В ядре Linux нити, управляемые ядром, устройством не отличаются от процесса. Нить -- это просто процесс, который создан уникальным (существующим только в Linux) системным вызовом clone(2); другие процедуры, такие как переносимая версия pthread_create(3), также реализованы с помощью clone(2). Таким образом, если процессы A и B являются братьями, нить A не может подождать с помощью wait() процесс, порожденный потоком B или его потомками, потому что дядя не может ждать с помощью wait() своих племянников. В некоторых Unix-подобных системах, где множественные нити реализованы как принадлежащие одиночному процессу, нить A может ждать с помощью wait() процессы, порожденные своей сестринской нитью B; вам придется переписать код, который делает такие допущения, чтобы он заработал под Linux.

СООТВЕТСТВИЕ СТАНДАРТАМ
SVr4, POSIX.1

СМОТРИ ТАКЖЕ
clone(2), signal(2), wait4(2), pthread_create(3), signal(7)