2011-12-16 270 views
18

有人告诉我,当你在linux中杀死父进程时,孩子会死。
但我怀疑它。所以我写了两篇的bash脚本,其中father.sh将调用child.sh父进程在Linux中被终止后为什么子进程还活着?

这里是我的脚本:

enter image description here

现在我跑bash father.sh,你可以检查它ps -alf enter image description here

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

任何人都可以解释为什么吗?

THX

+5

我认为你可以削减80%的文字和所有图片,并且仍然保留在这个问题中重要的一切。 – ndemou 2015-10-27 11:02:02

回答

26

没有,当你独自一人杀死一个过程,它不会杀死孩子。

你,如果你想给定组的所有进程接收信号

kill -9 -parentpid 

否则将信号发送到进程组,孤儿将被链接到init,如由你的第三个截图(孩子的PPID已成为1)。

+0

其中'thepidhere`通常是父进程的PID,但可以使用`ps -eo“%p%r%c%a”`确定。 +1。 – 2011-12-16 11:23:36

+0

进程组标识与父标识相同。你可以详细说明如何阻止它们全部 – 2011-12-16 15:38:22

+13

只是为了澄清fge的命令,如果它不明显,你会传递父代码作为负数,例如,如果父母的pid是1234,你想杀了-1234 – frankc 2011-12-16 16:01:31

4

-bash:杀:(-123) - 没有这样的进程

在交互式会话Terminal.app前台进程组ID号和后台进程组ID号是由设计时的工作不同控制/监视模式启用。换句话说,如果您在启用作业控制的Terminal.app会话中背景命令,后台进程的$! pid实际上是一个新的进程组标识号(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
pkill -TERM -P <ProcessID> 

这将扼杀了家长和孩子

5

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

杀死父亲后,你看到孩子还活着的原因是因为孩子只有在选择处理SIGKILL事件后才会死亡。它不必马上处理它。你的脚本运行一个sleep()命令,在睡眠完成之前它不会被唤醒以处理任何事件。

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

处理组中的杀是不同的,并且被用于杀死兄妹,并且由处理组#。也许很重要的一点是,“杀死一个进程”本身并不是以人类的方式“杀戮”,在那里你期望进程被销毁,所有的记忆都会像以前一样回归。它只是将特定的事件发送给它处理的过程。如果这个过程没有正确处理,那么过了一段时间,操作系统就会出现并强行进行“清理”。因为孩子(甚至父母)可能已经将某些东西写入磁盘并等待I/O完成或执行可能危及系统稳定性的其他关键任务,或者正在等待I/O完成或执行一些可能危及系统稳定性的其他关键任务,因此它(杀戮)不会立即发生。文件完整性。

相关问题