Операционная система UNIX - страница 71

стр.

, waitid(2) и waitpid(2):

>#include

>#include


>pid_t wait(int* stat_loc);

>int waitpid(idtype_t idtype, id_t id,

>siginfo_t * infop, int options);

>pid_t waitpid(pid_t pid, int *stat_loc, int options);

Первый из этих вызовов wait(2) обладает самой ограниченной функциональностью — он позволяет заблокировать выполнение процесса, пока кто-либо из его непосредственных потомков не прекратит существование. Вызов wait(2) немедленно возвратит состояние уже завершившегося дочернего процесса в переменной >stat_loc, если последний находится в состоянии зомби. Значение >stat_loc может быть проанализировано с помощью следующих макроопределений:

>WIFEXITED(status)Возвращает истинное (ненулевое) значение, если процесс завершился нормально.
>WEXITSTATUS(status)Если WIFEXITED(status) не равно нулю, определяет код возврата завершившегося процесса (аргумент функции exit(2)).
>WIFSIGNALLED(status)Возвращает истину, если процесс завершился по сигналу.
>WTERMSIG(status)Если WIFSIGNALLED(status) не равно нулю, определяет номер сигнала, вызвавшего завершение выполнения процесса.
>WCOREDUMP(status)Если WIFSIGNALLED(status) не равно нулю, макрос возвращает истину в случае создания файла core.

Системный вызов waitid(2) предоставляет больше возможностей для контроля дочернего процесса. Аргументы >idtype и >id определяют, за какими из дочерних процессов требуется следить:

Значение аргумента idtypeОписание
>P_PIDwaitid(2) блокирует выполнение процесса, следя за потомком, PID которого равен >id.
>P_PGIDwaitid(2) блокирует выполнение процесса, следя за потомками, идентификаторы группы которых равны >id.
>P_ALLwaitid(2) блокирует выполнение процесса, следя за всеми непосредственными потомками.

Аргумент >options содержит флаги, объединенные логическим ИЛИ, определяющие, за какими изменениями в состоянии потомков следит waitid(2):

Флаги аргумента optionsОписание
>WEXITEDПредписывает ожидать завершения выполнения процесса.
>WTRAPPEDПредписывает ожидать ловушки (trap) или точки останова (breakpoint) для трассируемых процессов.
>WSTOPPEDПредписывает ожидать останова процесса из-за получения сигнала.
>WCONTINUEDПредписывает вернуть статус процесса, выполнение которого было продолжено после останова.
>WNOHANGПредписывает завершить свое выполнение, если отсутствует статусная информация (т.е. отсутствует ожидаемое событие).
>WNOWAITПредписывает получить статусную информацию, но не уничтожать ее, оставив дочерний процесс в состоянии ожидания.

Аргумент >infop указывает на структуру >siginfo_t, которая будет заполнена информацией о потомке. Мы рассмотрим эту структуру в следующем разделе.

Функция waitpid(2), как и функции wait(2) и waitid(2), позволяет контролировать определенное множество дочерних процессов.

В заключение для иллюстрации описанных в этом разделе системных вызовов приведем схему работы командного интерпретатора при запуске команды.

>...

>/* Вывести приглашение shell*/

>write(1, "$ ", 2);

>/* Считать пользовательский ввод */

>get_input(inputbuf);

>/* Произвести разбор ввода: выделить команду cmd

>   и ее аргументы arg[] */

>parse_input(inputbuf, and, arg);

>/* Породить процесс */

>pid = fork();

>if (pid == 0) {

> /* Запустить программу */

> execvp(cmd, arg);

> /* При нормальном запуске программы эта часть кода

>    выполняться уже не будет — можно смело выводить

>    сообщение об ошибке */

> pexit(cmd);

>} else

> /* Родительский процесс (shell) ожидает завершения

>    выполнения потомка */

> wait(&status);

>...

Сигналы

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

Сигналы появились уже в ранних версиях UNIX, но их реализация не была достаточно надежной. Сигнал мог быть "потерян", возникали также определенные сложности с отключением (блокированием) сигналов на время выполнения критических участков кода. В последующие версии системы, как BSD, так и System V, были внесены изменения, позволившие реализовать