在Linux中为什么父进程被杀后子进程还活着?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (4)
  • 关注 (0)
  • 查看 (3570)

有人告诉我,当你在Linux中杀死一个父进程时,子进程就会死掉。

但我不怎么相信。所以我写了两个bash脚本father.sh会调用child.sh

这是我的脚本:

现在我跑bash father.sh,检查一下ps -alf

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

有人能解释一下是原因吗?

谢谢!!

提问于
用户回答回答于
pkill -TERM -P <ProcessID>

这将杀死所有人23333

用户回答回答于

答案是错误的。一般杀死父进程也会杀子进程。

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

为什么是PPID#1?父进程已经死亡,不再在进程表中。child.sh并不会莫名其妙地连接到init。它根本没有运行的父进程。说它和init相关联是因为会产生一个假象:杀死父进程会使祖父母成为孩子的主人。两者都是不正确的。该子进程仍然存在于进程表中并且正在运行,但是不会处理基于它的进程ID的新事件,直到它处理完SIGKILL。这意味着孩子是一个僵尸前,走路死亡,有被贴上标签的危险。

杀死进程组是不同的,用来杀死兄弟姐妹,并且通过进程组#来杀死进程。也许同样重要的是要注意,“杀死一个进程”本身并不是以人类的方式“杀戮”,在那里你期望进程被摧毁,所有的记忆都会像以前一样回归。它只是发送一个特定的事件,其中很多,它处理的过程。如果这个过程没有正确处理,那么一段时间以后,操作系统会强行进行“清理”。

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

原谅我把技术搞到家庭纷争上。。。emmm

用户回答回答于

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

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

但是,在没有启用作业控制的脚本中,情况可能并非如此!后台进程的pid可能不是一个新的pgid,而是一个正常的pid!这是什么导致错误消息-bash: kill: (-123) - No such process,试图杀死一个进程组,但只指定一个正常的pid(而不是一个pgid)的kill命令。

# 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
}
用户回答回答于

不,当你独自杀死一个进程的时候,它不会杀死那些子进程的。

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

kill -9 -parentpid

否则,没有父进程的子进程将被链接到init,就如你的第三个屏幕截图所示。

扫码关注云+社区

领取腾讯云代金券