Если я fork
дочерний процесс и выходы дочернего процесса перед родительскими вызовами waitpid
, затем информация о статусе выхода, которая установлена waitpid
все еще допустимый? Если так, когда делает это, становятся не допустимыми; т.е. как я удостоверяюсь, что могу звонить waitpid
на дочернем pid и продолжают получать допустимую информацию статуса выхода после произвольного количества времени, и как я "моюсь" (скажите ОС, что я больше не интересуюсь информацией о статусе выхода для законченного дочернего процесса)?
Я играл вокруг со следующим кодом, и кажется, что информация о статусе выхода допустима в течение по крайней мере нескольких секунд после дочерних концов, но я не знаю, как долго или как сообщить ОС, что я не буду звонить waitpid
снова:
#include <assert.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
int main()
{
pid_t pid = fork();
if (pid < 0) {
fprintf(stderr, "Failed to fork\n");
return EXIT_FAILURE;
}
else if (pid == 0) { // code for child process
_exit(17);
}
else { // code for parent
sleep(3);
int status;
waitpid(pid, &status, 0);
waitpid(pid, &status, 0); // call `waitpid` again just to see if the first call had an effect
assert(WIFEXITED(status));
assert(WEXITSTATUS(status) == 17);
}
return EXIT_SUCCESS;
}
Да, waitpid
будет работать после выхода ребенка. ОС будет сохранять запись дочернего процесса в таблице процессов (включая статус выхода) до тех пор, пока родитель не вызовет waitpid
(или другую функцию wait
-семейства) или пока родительский процесс не выйдет ( в этот момент статус собирается процессом init
). Вот что такое «зомби-процесс»: процесс, завершившийся через, все еще находится в таблице процессов именно для этой цели.
Запись процесса в таблице должна исчезнуть после первого вызова waitpid
. Я подозреваю, что причина того, что в вашем примере вы, кажется, можете дважды вызвать waitpid
, просто потому, что waitpid
не изменит аргумент status
, если pid
больше не существует. Таким образом, первый вызов должен работать и заполнять статус
, а второй вызов должен возвращать код ошибки и не изменять статус
. Вы можете проверить это, проверив возвращаемые значения вызовов waitpid
и / или используя две разные переменные status
.
ОС сохраняет завершенный процесс в состоянии зомби до тех пор, пока его родительский процесс (которым может быть init
, если исходный родительский процесс завершился ранее) не соберет это статус выхода с системным вызовом wait (2)
. Итак, ответ - статус выхода процесса не становится недействительным .
Да.
Из страницы руководства :
Дочерний элемент, который завершается, но не имеет Ждали, когда станет «зомби». Ядро поддерживает минимальный набор информация о зомби-процессе (PID, статус завершения, ресурс информация об использовании), чтобы разрешить родитель, чтобы позже выполнить ожидание получить информацию о ребенке.