如果我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/