[英]Does waitpid yield valid status information for a child process that has already exited?
If I fork
a child process, and the child process exits before the parent calls waitpid
, then is the exit status information that is set by waitpid
still valid? 如果我
fork
子进程,并且子进程在父调用waitpid
之前退出,那么waitpid
设置的退出状态信息是否仍然有效? If so, when does it become not valid; 如果是的话,什么时候变得无效; ie, how do I ensure that I can call
waitpid
on the child pid and continue to get valid exit status information after an arbitrary amount of time, and how do I "clean up" (tell the OS that I am no longer interested in the exit status information for the finished child process)? 即,如何确保我可以在子pid上调用
waitpid
并在任意时间后继续获取有效的退出状态信息,以及如何“清理”(告诉操作系统我不再对已完成的子进程的退出状态信息)?
I was playing around with the following code, and it appears that the exit status information is valid for at least a few seconds after the child finishes, but I do not know for how long or how to inform the OS that I won't be calling waitpid
again: 我正在玩下面的代码,似乎退出状态信息在孩子完成后至少几秒钟有效,但我不知道多长时间或如何通知操作系统我不会再次调用
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;
}
Yes, waitpid
will work after the child has exited. 是的,
waitpid
将在孩子退出后工作。 The OS will keep a child process' entry in the process table (including exit status) around until the parent calls waitpid
(or another wait
-family function) or until the parent exits (at which point the status is collected by the init
process). 操作系统将保持子进程在进程表中的条目(包括退出状态),直到父进程调用
waitpid
(或另一个wait
-family函数)或直到父进程退出(此时init
进程收集状态) 。 This is what a "zombie" process is: a process that has exited by is still resident in the process table for exactly this purpose. 这就是“僵尸”进程的原因:已经退出的进程仍然驻留在进程表中以实现此目的。
The process' entry in the table should go away after the first call to waitpid
. 第一次调用
waitpid
后,表中的进程'条目应该消失。 I suspect the reason that in your example you seem to be able to call waitpid
twice is simply because waitpid
will not modify the status
argument if pid
no longer exists. 我怀疑在你的例子中你似乎能够两次调用
waitpid
原因仅仅是因为如果pid
不再存在, waitpid
将不会修改status
参数。 So the first call should be working and filling in status
, and the second call should be returning an error code and not changing status
. 所以第一次调用应该工作并填写
status
,第二次调用应该返回错误代码而不是改变status
。 You can verify this by inspecting the return values of the waitpid
calls and/or using two different status
variables. 您可以通过检查
waitpid
调用的返回值和/或使用两个不同的status
变量来验证这一点。
The OS keeps terminated process in a zombie state until its parent (which might be the init
if the original parent process terminated earlier) collects that exit status with wait(2)
system call. 操作系统将僵持状态的终止进程保持到其父级(如果原始父进程先前终止可能是
init
),则使用wait(2)
系统调用收集该退出状态。 So the answer is - the exit status of the process does not become invalid . 所以答案是 - 进程的退出状态不会变得无效 。
Yes. 是。
A child that terminates, but has not been waited for becomes a "zombie".
终止但尚未等待的孩子变成了“僵尸”。 The kernel maintains a minimal set of information about the zombie process (PID, termination status, resource usage information) in order to allow the parent to later perform a wait to obtain information about the child.
内核维护有关僵尸进程(PID,终止状态,资源使用信息)的最小信息集,以便允许父进程稍后执行等待以获得关于子进程的信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.