为什么在Linux进程中父进程被杀后,子进程仍处于活动状态?

时间:2011-12-16 11:13:39

标签: linux bash process

有人告诉我,当你在linux中杀死一个父进程时,孩子就会死掉 但我对此表示怀疑。所以我写了两个bash脚本,其中father.sh将调用child.sh

这是我的剧本:

enter image description here

现在我运行bash father.sh,您可以检查ps -alf enter image description here

然后我通过father.sh杀了kill -9 24588,我猜想应该终止子进程但不幸的是我错了。 enter image description here

有人可以解释为什么吗?

THX

4 个答案:

答案 0 :(得分:39)

不,当你单独杀死一个进程时,它不会杀死孩子。

如果您希望给定组的所有进程都接收信号,则必须将信号发送到进程组

kill -9 -parentpid

否则,孤儿将被链接到init,如您的第三个屏幕截图所示(孩子的PPID已变为1)。

答案 1 :(得分:6)

  

-bash:kill:( - 123) - 没有这样的过程

在交互式Terminal.app会话中,当启用作业控制/监视模式时,前台进程组ID号和后台进程组ID号在设计上是不同的。换句话说,如果您在启用作业控制的Terminal.app会话中后台命令,则后台进程的$! pid实际上是一个新的进程组ID号(pgid)。

但是,在没有启用作业控制的脚本中,情况可能并非如此!背景过程的pid可能不是一个新的pgid,而是一个普通的pid!这就是导致错误消息-bash: kill: (-123) - No such process的原因,试图杀死一个进程组,但只为kill命令指定了一个普通的pid(而不是pgid)。

# the following code works in Terminal.app because $! == $pgid
{
sleep 100 &
IFS=" " read -r pgid <<EOF
$(ps -p $! -o pgid=)
EOF
echo $$ $! $pgid
sleep 10
kill -HUP -- -$!
#kill -HUP --  -${pgid}  # use in script
}

答案 2 :(得分:6)

一般杀死父母也会杀死孩子。

您在杀死父亲后看到孩子仍然活着的原因是因为孩子在选择处理SIGKILL事件后才会死亡。它不必立即处理它。您的脚本正在运行sleep()命令,在睡眠完成之前,该命令不会被唤醒以处理任何事件。

为什么PPID#1?父母已经死亡,不再在流程表中。 child.sh现在没有莫名其妙地与链接到init。它根本没有正在运行的父级。说它链接到init会产生一种印象,即如果我们以某种方式离开init,那init就可以控制关​​闭进程。它还会造成一种印象,即杀死父母会使祖父母成为孩子的主人。两者都不是真的。该子进程仍然存在于进程表中并且正在运行,但是在处理SIGKILL之前,不会处理基于它的进程ID的新事件。这意味着孩子是一个前僵尸,行尸走肉,有被贴上标签的危险。

在进程组中杀戮是不同的,用于通过进程组#终止兄弟。注意到&#34;杀死进程&#34;可能也很重要。不是&#34;杀戮&#34;本身,在人类的方式,你期望进程被销毁,所有内存返回,就好像它从来没有。它只是将许多特定事件发送给它要处理的进程。如果进程没有正确处理,那么一段时间后操作系统会出现并清理它&#34;强制

它(杀戮)不会立即发生,因为孩子(甚至父母)可能已经写了一些东西到磁盘并等待I / O完成或做一些可能危及系统稳定性的其他关键任务或文件完整性。

答案 3 :(得分:2)

pkill -TERM -P <ProcessID>

这会杀死父母和孩子