waitpid приводит к допустимой информации о статусе для дочернего процесса, который уже вышел?

Если я 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;
}
7
задан Daniel Trebbien 20 May 2010 в 16:01
поделиться

3 ответа

Да, waitpid будет работать после выхода ребенка. ОС будет сохранять запись дочернего процесса в таблице процессов (включая статус выхода) до тех пор, пока родитель не вызовет waitpid (или другую функцию wait -семейства) или пока родительский процесс не выйдет ( в этот момент статус собирается процессом init ). Вот что такое «зомби-процесс»: процесс, завершившийся через, все еще находится в таблице процессов именно для этой цели.

Запись процесса в таблице должна исчезнуть после первого вызова waitpid . Я подозреваю, что причина того, что в вашем примере вы, кажется, можете дважды вызвать waitpid , просто потому, что waitpid не изменит аргумент status , если pid больше не существует. Таким образом, первый вызов должен работать и заполнять статус , а второй вызов должен возвращать код ошибки и не изменять статус . Вы можете проверить это, проверив возвращаемые значения вызовов waitpid и / или используя две разные переменные status .

12
ответ дан 6 December 2019 в 11:46
поделиться

ОС сохраняет завершенный процесс в состоянии зомби до тех пор, пока его родительский процесс (которым может быть init , если исходный родительский процесс завершился ранее) не соберет это статус выхода с системным вызовом wait (2) . Итак, ответ - статус выхода процесса не становится недействительным .

3
ответ дан 6 December 2019 в 11:46
поделиться

Да.

Из страницы руководства :

Дочерний элемент, который завершается, но не имеет Ждали, когда станет «зомби». Ядро поддерживает минимальный набор информация о зомби-процессе (PID, статус завершения, ресурс информация об использовании), чтобы разрешить родитель, чтобы позже выполнить ожидание получить информацию о ребенке.

2
ответ дан 6 December 2019 в 11:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: