pid_t wait(int *status); pid_t waitpid(pid_t pid, int *status, int options);
ОПИСАНИЕ
Функция
wait
приостанавливает выполнение текущего процесса до тех пор, пока
дочерний процесс не завершится, или до появления сигнала,
который либо завершает текущий процесс, либо требует вызвать
функцию-обработчик. Если дочерний процесс к моменту вызова функции
уже завершился (так называемый "зомби" ("zombie")), то функция немедленно
возвращается. Системные ресурсы, связанные с дочерним процессом,
освобождаются.
Функция
waitpid
приостанавливает выполнение текущего процесса до тех пор, пока
дочерний процесс, указанный в параметре
pid,
не завершит выполнение, или пока не появится сигнал, который либо
завершает текущий процесс либо требует вызвать функцию-обработчик.
Если указанный дочерний процесс к моменту вызова функции уже
завершился (так называемый "зомби"), то функция немедленно
возвращается. Системные ресурсы, связанные с дочерним процессом,
освобождаются.
Параметр
pid
может принимать несколько значений:
< -1
означает, что нужно ждать любого дочернего процесса, идентификатор
группы процессов которого равен абсолютному значению
pid.
-1
означает ожидание любого дочернего процесса; функция
wait
ведет себя точно так же.
0
означает ожидание любого дочернего процесса, идентификатор группы
процессов которого равен идентификатору текущего процесса.
> 0
означает ожидание дочернего процесса, чей идентификатор равен
pid.
Значение
options
создается путем логического сложения нескольких следующих
констант:
WNOHANG
означает немедленное возвращение управления, если ни один дочерний процесс
не завершил выполнение.
WUNTRACED
означает возврат управления и для остановленных (но не отслеживаемых) дочерних
процессов, о статусе которых еще не было сообщено. Статус для отслеживаемых
остановленных подпроцессов также обеспечивается без этой опции.
(Только для параметров Linux, смотрите разделы ниже.)
Если
status
не равен
NULL,
то функции
wait
и
waitpid
сохраняют информацию о статусе в переменной, на которую указывает
status.
Этот статус можно проверить с помощью нижеследующих макросов (они
принимают в качестве аргумента буфер (типа int), --- а не указатель
на буфер!):
WIFEXITED(status)
не равно нулю, если дочерний процесс успешно завершился.
WEXITSTATUS(status)
возвращает восемь младших битов значения, которое вернул завершившийся
дочерний процесс. Эти биты могли быть установлены в аргументе
функции
exit()
или в аргументе оператора
return
функции
main().
Этот макрос можно использовать, только если
WIFEXITED
вернул ненулевое значение.
WIFSIGNALED(status)
возвращает истинное значение, если дочерний процесс завершился из-за
необработанного сигнала.
WTERMSIG(status)
возвращает номер сигнала, который привел к завершению дочернего
процесса. Этот макрос можно использовать, только если
WIFSIGNALED
вернул ненулевое значение.
WIFSTOPPED(status)
возвращает истинное значение, если дочерний процесс, из-за которого
функция вернула управление, в настоящий момент остановлен; это
возможно, только если использовался флаг
WUNTRACED
или когда подпроцесс отслеживается (см.
ptrace(2)).
WSTOPSIG(status)
возвращает номер сигнала, из-за которого дочерний процесс был
остановлен. Этот макрос можно использовать, только если
WIFSTOPPED
вернул ненулевое значение.
Некоторые версии Unix (например Linux, Solaris, но не AIX, SunOS)
также определяют макрос
WCOREDUMP(status)
для проверки того, не вызвал ли дочерний процесс ошибку ядра.
Используйте это только в структуре #ifdef WCOREDUMP ... #endif.
ВОЗВРАЩАЕМЫЕ ЗНАЧЕНИЯ
Возвращает идентификатор дочернего процесса, который завершил выполнение,
или ноль, если использовался
WNOHANG
и ни один дочерний процесс пока еще недоступен, или -1 в случае ошибки
(в этом случае переменной
errno
присваивается соответствующее значение).
НАЙДЕННЫЕ ОШИБКИ
ECHILD
процесс, указанный в
pid,
не существует или не является дочерним процессом текущего процесса.
(Это может случиться и с собственным дочерним процессом, если
обработчик сигнала SIGCHLD установлен в SIG_IGN. Смотри также главу
ЗАМЕЧАНИЯ по поводу многозадачности процессов.)
EINVAL
Аргумент
options
неверен.
EINTR
Использовался флаг
WNOHANG,
и был получен необработанный сигнал или
SIGCHLD.
Стандарт Single Unix Specification описывает флаг SA_NOCLDWAIT (не
поддерживается в Linux), если он установлен или обработчик
сигнала SIGCHLD устанавливается в SIG_IGN,
то завершившиеся дочерние процессы не становятся
зомби, а вызов
wait()
или
waitpid()
блокируется, пока все дочерние процессы не завершатся, а затем
устанавливает переменную
errno
равной ECHILD.
Стандарт POSIX оставляет неопределенным поведение при
установке SIGCHLD в SIG_IGN.
поздние стандарты, включая SUSv2 и POSIX 1003.1-2001,
определяют поведение, только что описанное как опция
совместимости с XSI.
Linux не следует второму варианту:
если вызов
wait() или waitpid()
сделан в то время, когда SIGCHLD игнорируется,
то вызов ведет себя, как если бы SIGCHLD не игнорировался,
то есть вызов блокирует до завершения работы следующего подпроцесса
и возврата идентификатора процесса PID и статуса этого подпроцесса.
ЗАМЕЧАНИЯ ПО LINUX
В ядре Linux задачи, управляемые ядром, по внутреннему устройству не отличаются от
процесса. Задача (thread) -- это простой процесс,
который создан специфичным для Linux системным вызовом
clone(2);
другие процедуры, типа портируемой
pthread_create(3),
также реализованы с помощью
clone(2).
До Linux 2.4, задачи были частным случаем процесса,
и последовательность одной группы задач не могла ожидать дочерний процесс
или другую группу задач, даже если воследняя принадлежит к этой-же группе
задач. Однако, POSIX предопределяет такие особенности, и с Linux 2.4
группа задач может, и по умолчанию будет ожидать дочерний процесс другой группы задач
в этой-же группе задач.
Следующие специфичные для Linux
параметры
существуют для использования с дочерними процессами и
clone(2).
__WCLONE
только ожидает дочерние процессы. Если отменяется, то
ожидает только дочерних неклонированных процессов.
("клонированным" дочерним процессом является подпроцесс,
не отправляющий сигналов, или выдающий сигналы, отличающиеся от
SIGCHLD
своему родителю до завершения.)
Эта опция игнорируется, если определено
__WALL.
__WALL
(с Linux 2.4) Ожидает все дочерние процессы,
независимо от их типа ("клон" или "не-клон").
__WNOTHREAD
(С Linux 2.4) Не ожидать дочерние процессы или остальные задачи
в идентичной группе задач. Было параметром по умолчанию до Linux 2.4.