维基说“终止,但永远不会被其父一直在等待一个子进程将成为僵尸进程。” 我运行这个程序:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
pid_t pid, ppid;
printf("Hello World1\n");
pid=fork();
if(pid==0)
{
exit(0);
}
else
{
while(1)
{
printf("I am the parent\n");
printf("The PID of parent is %d\n",getpid());
printf("The PID of parent of parent is %d\n",getppid());
sleep(2);
}
}
}
这将创建一个僵尸进程,但我不明白为什么在这里创建了一个僵尸进程?
该程序的输出是
Hello World1
I am the parent
The PID of parent is 3267
The PID of parent of parent is 2456
I am the parent
The PID of parent is 3267
The PID of parent of parent is 2456
I am the parent
....
.....
但为什么是“子进程结束,但其父不娇娇”在这种情况下?
在你的代码中,对创建僵尸exit(0)
下面箭头评论):
pid=fork();
if (pid==0) {
exit(0); // <--- zombie is created on here
} else {
// some parent code ...
}
为什么? 因为你永远不wait
编辑就可以了。 当一些调用waitpid(pid)
将返回有关过程死后的信息,比如它的退出代码。 不幸的是,当程序退出,内核不能随便处置这个过程中进入,或返回代码将会丢失。 因此,等待有人来wait
就可以了,和周围离开这个进程入口,即使它并没有真正占用任何记忆,除了在进程表项-这正是被称为僵尸 。
你有几个选项,以避免产生僵尸:
加入waitpid()
某处父进程 。 举例来说,这样做会有所帮助:
pid=fork(); if (pid==0) { exit(0); } else { waitpid(pid); // <--- this call reaps zombie // some parent code ... }
执行双fork()
获取孙子和退出的孩子,而孙子还活着。 孙子将自动通过init
,如果他们的父母(我们的孩子)死了,如果孙去世,这意味着,它会自动wait
被编上init
。 换句话说,你需要做的是这样的:
pid=fork(); if (pid==0) { // child if (fork()==0) { // grandchild sleep(1); // sleep a bit to let child die first exit(0); // grandchild exits, no zombie (adopted by init) } exit(0); // child dies first } else { waitpid(pid); // still need to wait on child to avoid it zombified // some parent code ... }
明确忽略父SIGCHLD信号 。 当孩子死了,父母被发送SIGCHLD
信号,让它对儿童死亡反应。 你可以调用waitpid()
在接收到该信号,也可以安装明确忽略信号处理程序(使用signal()
或sigaction()
这将确保孩子不会成为僵尸。 换句话说,这样的事情:
signal(SIGCHLD, SIG_IGN); // <-- ignore child fate, don't let it become zombie pid=fork(); if (pid==0) { exit(0); // <--- zombie should NOT be created here } else { // some parent code ... }