Известно, что системный вызов fork() используется для создания нового процесса, который становится потомком вызывающего процесса.
После выхода дочерний элемент оставляет статус выхода, который должен быть возвращен родителю. Итак, когда ребенок заканчивает, он становится зомби.
Каждый раз, когда дочерний элемент выходит или останавливается, родителю отправляется сигнал SIGCHLD.
Родитель может использовать системный вызов wait() или waitpid() вместе с макросами WIFEXITED и WEXITSTATUS, чтобы узнать о состоянии его остановленного дочернего элемента.
(*) системный вызов wait(): приостанавливает выполнение вызывающего процесса до завершения одного из его дочерних процессов.
Синтаксис системного вызова wait():
pid_t wait(int *status);
(*) Системный вызов waitpid(): он приостанавливает выполнение вызывающего процесса до тех пор, пока дочерний процесс, указанный в аргументе pid, не изменит состояние.
Синтаксис системного вызова waitpid():
pid_t waitpid(pid_t pid, int *status, int options)
Значение pid может быть:
- Меньше -1: означает ожидание любого дочернего процесса, идентификатор группы процессов которого равен абсолютному значению pid.
- Равно -1: означает ожидание любого дочернего процесса.
- Равно 0: означает ожидание любого дочернего процесса, идентификатор группы процессов которого совпадает с идентификатором вызывающего процесса.
- Больше 0: означает ожидание дочернего процесса, идентификатор процесса которого равен значению pid.
- WIFEXITED и WEXITSTATUS – это две опции, которые можно использовать для определения статуса выхода дочернего элемента.
- WIFEXITED (статус): возвращает истину, если дочерний процесс завершился нормально.
- WEXITSTATUS (статус): возвращает статус выхода дочернего элемента. Этот макрос следует использовать, только если WIFEXITED вернул истину.
Ниже представлена реализация C, в которой дочерний элемент использует функцию execl(), но путь, указанный для execl(), не определен.
Давайте посмотрим, каково значение статуса выхода дочернего элемента, который получает родитель.
// Код C для определения состояния выхода дочернего процесса #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> // Код драйвера int main(void) { pid_t pid = fork(); if ( pid == 0 ) { /* Путь к файлу, переданному execl() не определен */ execl("/bin/sh", "bin/sh", "-c", "./nopath", "NULL"); } int status; waitpid(pid, &status, 0); if ( WIFEXITED(status) ) { int exit_status = WEXITSTATUS(status); printf("Статус выхода дочернего процесса был %d\n", exit_status); } return 0; } exit:
Здесь статус выхода 127, что указывает на некоторую проблему с путем или опечатку.
Несколько кодов статуса выхода перечислены ниже для получения дополнительной информации:
- 1: Прочие ошибки, такие как «делить на ноль» и другие недопустимые операции.
- 2: Отсутствует ключевое слово или команда, либо проблема с разрешением.
- 126: проблема с правами доступа или команда не является исполняемым файлом
- 128: недопустимый аргумент для выхода.