c - waitpid 是否为已经退出的子进程生成有效的状态信息?

标签 c fork waitpid posix-api

如果我fork一个子进程,子进程在父进程调用waitpid之前退出,那么就是waitpid<设置的退出状态信息 仍然有效?如果是这样,它什么时候变得无效?即,如何确保我可以在子 pid 上调用 waitpid 并在任意时间后继续获取有效的退出状态信息,以及如何“清理”(告诉操作系统我不再对完成的子进程的退出状态信息感兴趣)?

我在玩下面的代码,看起来退出状态信息在 child 完成后至少几秒钟内有效,但我不知道多长时间或如何通知操作系统我赢了再次调用 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将在 child 退出后工作。操作系统将在进程表中保留子进程的条目(包括退出状态),直到父进程调用 waitpid (或另一个 wait 系列函数)或直到父级退出(此时状态由 init 进程收集)。这就是“僵尸”进程:出于这个目的,已经退出的进程仍然驻留在进程表中。

在第一次调用 waitpid 后,表中的进程条目应该消失.我怀疑在您的示例中您似乎能够调用 waitpid 的原因两次仅仅是因为 waitpid不会修改 status参数如果 pid不复存在。所以第一个电话应该工作并填写 status , 第二次调用应该返回一个错误代码并且不改变 status .您可以通过检查 waitpid 的返回值来验证这一点调用和/或使用两个不同的 status变量。

关于c - waitpid 是否为已经退出的子进程生成有效的状态信息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2865640/

相关文章:

c - 为什么该行打印两次?

c - 在不保持父进程执行的情况下获取子进程的返回值

c++ - 函数导致巨大的内存泄漏?

objective-c - HDR 和全景图 : where to learn

C 保存 fork 的 pid

linux - 使用 fork() 和 wait() 的正确方法

linux - Linux中waitpid()的返回值

c - 在 C 中运行/暂停子进程?

c - 没有 <stdlib.h> 的自由指针

c - 从 C 到 D 的数组指针