Операционная система 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_PID | waitid(2) блокирует выполнение процесса, следя за потомком, PID которого равен >id . |
>P_PGID | waitid(2) блокирует выполнение процесса, следя за потомками, идентификаторы группы которых равны >id . |
>P_ALL | waitid(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, были внесены изменения, позволившие реализовать