[英]Why child process still alive after parent process was killed in Linux?
有人告诉我,当你在 linux 中杀死一个父进程时,子进程就会死亡。
但我对此表示怀疑。 所以我写了两个bash脚本,其中father.sh
会调用child.sh
这是我的脚本:
现在我运行bash father.sh
,你可以检查它ps -alf
然后,我杀了father.sh
通过kill -9 24588
,我猜子进程应该被终止但不幸的是我错了。
谁能解释一下为什么?
谢谢
不,当你单独杀死一个进程时,它不会杀死孩子。
如果您希望给定组的所有进程都接收信号,则必须将信号发送到进程组
例如,如果您的父进程 ID 的代码为 1234,则您必须指定 parentpid,添加符号减号,后跟您的父进程 ID:
kill -9 -1234
否则,孤儿将链接到init
,如您的第三张屏幕截图所示(孩子的 PPID 已变为 1)。
-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
}
pkill -TERM -P <ProcessID>
这将杀死父母和孩子
通常杀死父母也会杀死孩子。
你看到孩子在杀死父亲后还活着的原因是因为孩子只有在它“选择”(内核选择)处理 SIGKILL 事件后才会死亡。 它不必立即处理。 您的脚本正在运行 sleep() 命令(即在内核中),该命令在睡眠完成之前不会唤醒以处理任何事件。
为什么是 PPID #1? 父进程已经死亡,不再在进程表中。 child.sh 现在没有莫名其妙地链接到 init。 它只是没有正在运行的父级。 说它与 init 相关联会产生这样的印象:如果我们以某种方式离开 init,那么 init 可以控制关闭进程。 它还给人一种印象,即杀死父母会使祖父母成为孩子的主人。 两者都不是真的。 该子进程仍然存在于进程表中并且正在运行,但是在处理 SIGKILL 之前不会处理基于其进程 ID 的新事件。 这意味着孩子是前僵尸,行尸走肉,有被贴上标签的危险。
进程组中的killing不同,用于进程组#杀死兄弟姐妹和父进程。 同样重要的是要注意,“杀死一个进程”本身并不是“杀死”,在人性化的方式中,您希望进程被销毁并且所有内存都像从未被销毁一样返回。 它只是向进程发送一个特定的事件,在许多事件中进行处理。 如果进程没有正确处理它,那么过一段时间操作系统就会出现并强行“清理”。
它(杀死)不会立即发生,因为子进程(甚至父进程)可能已将某些内容写入磁盘并等待 I/O 完成或执行一些其他可能危及系统稳定性或文件完整性的关键任务。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.