Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учеб.пос.СП.doc
Скачиваний:
28
Добавлен:
31.03.2015
Размер:
1.33 Mб
Скачать
    1. Системные вызовы wait, waitpid и waitid

Системные вызовы wait, waitpid и waited ожидают, пока дочерний процесс не изменит свое состояние (приостановка, возобновление или завершение) и возвращают его вызывающей программе:

waitpid - ожидает изменения состояния дочернего процесса

#include <sys/wait.h>

pid_t waitpid (

pid_t pid, /* идентификатор процесса или группы процессов */

int *statusp, /* указатель на статус или NUUL */

int options /* флаги */

);

/* В случае успеха возвращает идентификатор процесса или 0, -1 в случае ошибки (код ошибки - в переменной errno) */

Аргумент pid принимает следующие значения: > 0 (ожидать изменение состояния дочернего процесса с указанным идентификатором); -1 (ожидать изменение состояния любого дочернего процесса); 0 (ожидать изменение состояния любого дочернего процесса, принадлежащего к той же группе процессов, что и вызывающий); < -1 (ожидать изменение состояния любого дочернего процесса, принадлежащего к группе процессов с идентификатором pid).

На выходе из waitpid вызывающий процесс получает идентификатор процесса-потомка в виде возвращаемого значения, чей идентификатор совпал с аргументом pid. Ноль возвращается только в том случае, когда был установлен флаг WNOHANG. Допускается ожидать изменения состояния только прямых потомков, порожденных системным вызовом fork. Ожидание процессов-внуков не допускается, даже если их родители (прямые потомки вызывающего процесса) к моменту вызова уже завершили свою работу. Осиротевшие процессы передаются под опекунство специального системного процесса. Как правило, процессы-предки заинтересованы в получении информации о состоянии своих потомков – в противном случае процессы-потомки по завершении превращаются в зомби и пребывают в таком виде, пока не завершит работу родительский процесс. Тогда системный процесс, ставший приемным родителем, сможет обратиться к вызову wait и удалить зомбированный процесс.

Системный вызов waitpid может вернуть состояние изменившего его дочернего процесса только один раз (такой дочерний процесс называется ожидаемый). Если в одной точке программы было получено состояние потомка и вдруг обнаружилось, что это не тот потомок, которого ожидали, то нет никакого способа вернуть результат обратно в систему, чтобы другой waitpid мог получить его.

Если к моменту вызова waitpid имеется ожидаемый дочерний процесс, соответствующий заданному аргументу pid, управление в вызывающую программу возвращается немедленно. Если потомок найден, но еще не изменил свое состояние, системный вызов waitpid блокируется до появления подходящего ожидаемого потомка. Если потомок не был найден, вызывающей программе возвращается значение -1 и код ошибки ECHILD. Это может произойти потому, что аргумент pid задан неправильно или процесс-потомок перестал быть ожидаемым, то есть его состояние уже было получено.

Если в качестве аргумента statusp передан непустой указатель, то по заданному адресу записывается код состояния потомка. Он представляет собой комбинацию аргумента системного вызова _exit или exit и числа, описывающего причину завершения или приостановки.

Последний аргумент options может содержать один или более флагов, объединенных операцией ИЛИ: WCONTINUED (сообщать о возобновлении работы потомка); WNOHANG (не ожидать потомка, если он еще не изменил свое состояние, возвращать 0 вместо идентификатора процесса); WUNTRACED (сообщать о приостановке в работе потомка). Приведем несколько примеров, использующих системный вызов waitpid:

waitpid(pid, &status, 0) /* ожидать завершения потомка pid и получить код завершения*/

pid = waitpid(-1, NULL, 0) /* ожидать завершения любого из потомков, без получения кода завершения*/

Второй представитель группы системных вызовов wait представляет собой упрощенный вариант waitpid и эквивалентен вызову последнего с аргументом pid, равным -1, и с аргументом options равным нулю:

wait - ожидает завершения дочернего процесса

#include <sys/wait.h>

pid_t wait (

int *statusp, /* указатель на статус или NUUL */

);

/* Возвращает идентификатор процесса или -1 в случае ошибки (код ошибки - в переменной errno) */

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