Почему waitpid(-1, &status, 0) вообще не приостанавливает процесс без дочерних элементов?
Я не очень хорошо понимаю функцию waitpid(). В руководстве сказано:
The wait() system call suspends execution of the calling process until one of its children terminates. The call wait(&status) is equivalent to: waitpid(-1, &status, 0);
Источник: http://manpages.ubuntu.com/manpages/raring/man2/wait.2.html
Насколько я понимаю, это: если у меня есть процесс, а не дочерний процесс, то, что так всегда и называется waitpid(-1, &status, 0)
функционировать, тогда процесс должен зависнуть и не продолжаться, потому что никогда не может быть изменения состояния без дочерних элементов, и поэтому процесс просто висит там, ожидая, пока дочерний процесс не изменит состояние, которое никогда не произойдет в этом случае, но это понимание кажется быть неправильным, потому что приведенный ниже код не зависает в функции waitpid(). Вместо этого он возвращает -1 для ошибки, которая вероятна, потому что не было никакого дочернего процесса, но, как я понимаю в соответствии с руководством, программа должна просто зависнуть в / в функции waitpid() и ждать, пока дочерний процесс изменит состояние. Пока нет дочернего элемента, поэтому нет изменения статуса, поэтому он должен просто зависнуть в функции waitpid() и ждать и ждать. Приведенный ниже код никогда не должен достигать оператора printf(), но вместо этого он достигает функции printf().
Этот код только для демонстрации целей:
#include <sys/wait.h>
#include <sys/types.h>
#include <stdio.h>
int main() {
int status;
pid_t pid;
pid = waitpid(-1, &status, 0);
printf("%i\n", (int) pid); // pid returns -1
return 0;
}
Эта программа выполняется до конца, но, насколько я понимаю, в соответствии с руководством не должна. Что не так с моими рассуждениями?
2 ответа
Ясно, что намерение состоит в том, что, возвращая -1, это указывает на то, что нет дочерних элементов, которых нужно ждать (в некотором смысле, все дочерние элементы завершились).
Проверьте errno
чтобы узнать, почему waitpid вернул -1:
ECHILD (для wait ()) У вызывающего процесса нет ожидающих детей.
ECHILD (для waitpid () или waitid ()) Процесс, указанный в pid (waitpid ()) или idty pe и id (waitid ()), не существует или не является дочерним элементом вызывающего процесса. (Это может произойти для собственного ребенка, если для SIGCHLD установлено значение SIG_IGN. См. Также раздел "Примечания Linux" о потоках.)
EINTR WNOHANG не был установлен, и был обнаружен незаблокированный сигнал или SIGCHLD; см сигнал (7).
EINVAL Аргумент options недействителен.