对c编程中的"zombie processes"感到困惑
Confused on "zombie processes" in c programming
Question: How can I determine which one produces a "zombie process"
// Case 1
while(fork())
;
exit(0);
// Case 2
while(!fork())
;
exit(0);
我知道 "zombie" 是 - 当进程终止但仍在消耗资源时。 (或者至少我认为就是这样)
我认为情况 1 是 产生 僵尸进程的情况,因为它将 return -1出现错误,while(-1) = true 所以它会继续分叉?我不太确定。任何见解都会很棒,
顺便说一句:此代码在 Linux 环境中 运行 c 编程语言
提前致谢
僵尸进程是 child 终止的进程,但尚未被 parent 等待。 Child 进程通常由 fork 创建:
int pid = fork();
if (pid < 0) {
// fork failed
} else if (pid == 0) {
// this is the child process
}
// this is the parent
fork
returns 0 到 child 进程,正 pid 到 parent。他们的终止有两种情况:
child 在 parent 之前退出,然后 child 成为 "zombie" 进程,直到 parent 调用等待系列函数获取 child 的退出状态。
parent在child之前退出,然后child会re-parented到init进程,init进程会调用wait child 退出。这是有效的,因为 parent 将在其 child 退出时接收 SIGCHLD 信号,并且它可以在信号处理程序中调用等待。所以在这种情况下,不会创建僵尸。
此外,请注意 posix 定义如果 SIGCHLD 被 parent 忽略,则不会创建僵尸:
POSIX.1-2001 specifies that if the disposition of SIGCHLD is set to SIG_IGN or the SA_NOCLDWAIT flag is set for SIGCHLD (see sigaction(2)), then children that terminate do not
become zombies and a call to wait() or waitpid() will block until all children have terminated, and then fail with errno set to ECHILD. (The original POSIX standard left the
behavior of setting SIGCHLD to SIG_IGN unspecified. Note that even though the default disposition of SIGCHLD is "ignore", explicitly setting the disposition to SIG_IGN results
in different treatment of zombie process children.)
对于OP中的两种情况:
// Case 1
while(fork()) // same as while(fork() != 0)
;
exit(0);
// Case 2
while(!fork()) // same as while(fork() == 0)
;
exit(0);
第一个代码一直在parent中分叉,无论成功与否,结果children将立即退出,因为return值为0。由于parent挂在while循环里,不管fork成功还是失败(fork only returns 0 for children),所有的children都会变成zombie。
对于第二种情况,parent在fork returns时立即退出,但是child会继续fork,而这个child会再次做同样的事情,即它会立即退出,它创建的 child 将继续分叉。在这种情况下,由于 parent 退出,其所有 children 将重新 parent 初始化进程,因此不会创建僵尸。
Question: How can I determine which one produces a "zombie process"
// Case 1
while(fork())
;
exit(0);
// Case 2
while(!fork())
;
exit(0);
我知道 "zombie" 是 - 当进程终止但仍在消耗资源时。 (或者至少我认为就是这样)
我认为情况 1 是 产生 僵尸进程的情况,因为它将 return -1出现错误,while(-1) = true 所以它会继续分叉?我不太确定。任何见解都会很棒,
顺便说一句:此代码在 Linux 环境中 运行 c 编程语言
提前致谢
僵尸进程是 child 终止的进程,但尚未被 parent 等待。 Child 进程通常由 fork 创建:
int pid = fork();
if (pid < 0) {
// fork failed
} else if (pid == 0) {
// this is the child process
}
// this is the parent
fork
returns 0 到 child 进程,正 pid 到 parent。他们的终止有两种情况:
child 在 parent 之前退出,然后 child 成为 "zombie" 进程,直到 parent 调用等待系列函数获取 child 的退出状态。
parent在child之前退出,然后child会re-parented到init进程,init进程会调用wait child 退出。这是有效的,因为 parent 将在其 child 退出时接收 SIGCHLD 信号,并且它可以在信号处理程序中调用等待。所以在这种情况下,不会创建僵尸。
此外,请注意 posix 定义如果 SIGCHLD 被 parent 忽略,则不会创建僵尸:
POSIX.1-2001 specifies that if the disposition of SIGCHLD is set to SIG_IGN or the SA_NOCLDWAIT flag is set for SIGCHLD (see sigaction(2)), then children that terminate do not become zombies and a call to wait() or waitpid() will block until all children have terminated, and then fail with errno set to ECHILD. (The original POSIX standard left the behavior of setting SIGCHLD to SIG_IGN unspecified. Note that even though the default disposition of SIGCHLD is "ignore", explicitly setting the disposition to SIG_IGN results in different treatment of zombie process children.)
对于OP中的两种情况:
// Case 1
while(fork()) // same as while(fork() != 0)
;
exit(0);
// Case 2
while(!fork()) // same as while(fork() == 0)
;
exit(0);
第一个代码一直在parent中分叉,无论成功与否,结果children将立即退出,因为return值为0。由于parent挂在while循环里,不管fork成功还是失败(fork only returns 0 for children),所有的children都会变成zombie。
对于第二种情况,parent在fork returns时立即退出,但是child会继续fork,而这个child会再次做同样的事情,即它会立即退出,它创建的 child 将继续分叉。在这种情况下,由于 parent 退出,其所有 children 将重新 parent 初始化进程,因此不会创建僵尸。