如果我 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 不复存在。因此,第一个电话应该起作用并填写 status, ,第二个呼叫应返回错误代码,而不会更改 status. 。您可以通过检查返回值来验证这一点 waitpid 呼叫和/或使用两个不同的 status 变量。

其他提示

操作系统将终止过程保持在 僵尸州 直到其父母(这可能是 init 如果原始父进程较早终止)收集以 wait(2) 系统电话。因此答案是 - 流程的退出状态 不会变得无效.

是的。

来自 手册页:

一个终止但尚未等待的孩子变成了“僵尸”。内核保持了有关僵尸过程(PID,终止状态,资源使用信息)的最小信息,以便父​​母以后进行等待以获取有关孩子的信息。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top