有人告诉我,当你在linux中杀死一个父进程时,孩子就会死掉
但我对此表示怀疑。所以我写了两个bash脚本,其中father.sh
将调用child.sh
这是我的剧本:
现在我运行bash father.sh
,您可以检查ps -alf
然后我通过father.sh
杀了kill -9 24588
,我猜想应该终止子进程但不幸的是我错了。
有人可以解释为什么吗?
THX
答案 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>
这会杀死父母和孩子