代码之家  ›  专栏  ›  技术社区  ›  Daniel Trebbien

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

  •  7
  • Daniel Trebbien  · 技术社区  · 16 年前

    如果我 fork 子进程,子进程在父进程调用之前退出 waitpid ,则是由设置的退出状态信息 子进程 仍然有效吗?如果是这样的话,它什么时候失效,也就是说,我如何确保我可以打电话 子进程 在子PID上,并在任意时间后继续获取有效的退出状态信息,以及如何“清理”(告诉操作系统我不再对已完成的子进程的退出状态信息感兴趣)?

    我在玩下面的代码,在孩子完成后,退出状态信息似乎至少在几秒钟内有效,但我不知道要多长时间或如何通知操作系统我不会打电话。 子进程 再一次:

    #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;
    }
    
    3 回复  |  直到 16 年前
        1
  •  10
  •   Tyler McHenry    16 年前

    对, waitpid 孩子退出后将继续工作。操作系统将在进程表中保留一个子进程的条目(包括退出状态),直到父进程调用 子进程 (或其他) wait -或者直到父级退出(此时状态由 init 过程)。这就是“僵尸”进程的含义:已退出的进程仍驻留在进程表中,以达到此目的。

    表中的进程条目应在第一次调用 子进程 . 我怀疑在你的例子中,你似乎能够 子进程 两次只是因为 子进程 不会修改 status 论证如果 pid 不再存在。所以第一个电话应该是工作和填写 地位 ,第二个调用应返回错误代码而不更改 地位 . 您可以通过检查 子进程 呼叫和/或使用两种不同的 地位 变量。

        2
  •  3
  •   Nikolai Fetissov    16 年前

    操作系统将终止的进程保持在 zombie state 直到它的父(可能是 init 如果原始父进程提前终止)使用 wait(2) 系统调用。所以答案是-进程的退出状态 不会失效 .

        3
  •  2
  •   unwind    16 年前

    对。

    man page :

    终止,但没有终止的孩子 被等待变成“僵尸”。 内核维护一个最小的 关于僵尸过程的信息 (PID,终止状态,资源 使用信息)以便 要稍后执行等待的父级 获取关于孩子的信息。