为什么在Linux中杀死父进程后子进程还活着?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8533377/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why child process still alive after parent process was killed in Linux?
提问by u351545
Someone told me that when you killed a parent process in linux, the child would die.
But I doubt it. So I wrote two bash scripts, where father.sh
would invoke child.sh
有人告诉我,当你在 linux 中杀死一个父进程时,子进程就会死亡。
但我对此表示怀疑。所以我写了两个 bash 脚本,在哪里father.sh
会调用child.sh
Here is my script:
这是我的脚本:
Now I run bash father.sh
, you could check it ps -alf
现在我跑了bash father.sh
,你可以检查一下ps -alf
Then I killed the father.sh
by kill -9 24588
, and I guessed the child process should be terminated but unfortunately I was wrong.
然后我杀死了father.sh
by kill -9 24588
,我猜子进程应该被终止,但不幸的是我错了。
Could anyone explain why?
谁能解释一下为什么?
thx
谢谢
采纳答案by fge
No, when you kill a process alone, it will not kill the children.
不,当你单独杀死一个进程时,它不会杀死孩子。
You have to send the signal to the process groupif you want all processes for a given group to receive the signal
如果您希望给定组的所有进程都接收信号,则必须将信号发送到进程组
kill -9 -parentpid
Otherwise, orphans will be linked to init
, as shown by your third screenshot (PPID of the child has become 1).
否则,孤儿将链接到init
,如您的第三个屏幕截图所示(孩子的 PPID 已变为 1)。
回答by charz
-bash: kill: (-123) - No such process
-bash: kill: (-123) - 没有这样的过程
In an interactive Terminal.app session the foreground process group id number and background process group id number are different by design when job control/monitor mode is enabled. In other words, if you background a command in a job-control enabled Terminal.app session, the $!
pid of the backgrounded process is in fact a new process group id number (pgid).
在交互式 Terminal.app 会话中,当启用作业控制/监视模式时,前台进程组 ID 号和后台进程组 ID 号在设计上是不同的。换句话说,如果您在启用了作业控制的 Terminal.app 会话中后台执行命令$!
,则后台进程的pid 实际上是一个新的进程组 ID 号 (pgid)。
In a script having no job control enabled, however, this may not be the case! The pid of the backgrounded process may not be a new pgid but a normal pid! And this is, what causes the error message -bash: kill: (-123) - No such process
, trying to kill a process group but only specifying a normal pid (instead of a pgid) to the kill
command.
但是,在未启用作业控制的脚本中,情况可能并非如此!后台进程的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
}
回答by Muthu
pkill -TERM -P <ProcessID>
This will kill both Parent as well as child
这将杀死父母和孩子
回答by Beracah
Generally killing the parent also kills the child.
通常杀死父母也会杀死孩子。
The reason that you are seeing the child still alive after killing the father is because the child only will die after it chooses to handle the SIGKILL event. It doesn't have to handle it right away. Your script is running a sleep() command, which will not wake up to handle any events whatsoever until the sleep is completed.
您看到孩子在杀死父亲后还活着的原因是因为孩子只有在选择处理 SIGKILL 事件后才会死亡。它不必立即处理。您的脚本正在运行 sleep() 命令,该命令在睡眠完成之前不会唤醒以处理任何事件。
Why is PPID #1? The parent has died and is no longer in the process table. child.sh isn't linkedinexplicably to init now. It simply has no running parent. Saying it is linked to init creates the impression that if we somehow leave init, that init has control over shutting down the process. It also creates the impression that killing a parent will make the grandparent the owner of a child. Both are not true. That child process still exists in the process table and is running, but no new events based upon it's process ID will be handled until it handles SIGKILL. Which means that the child is a pre-zombie, walking dead, in danger of being labeled .
为什么是 PPID #1?父进程已经死亡,不再在进程表中。child.sh 现在没有莫名其妙地链接到 init。它只是没有正在运行的父级。说它与 init 相关联会产生这样的印象:如果我们以某种方式离开 init,那么 init 可以控制关闭进程。它还给人一种印象,即杀死父母会使祖父母成为孩子的主人。两者都不是真的。该子进程仍然存在于进程表中并且正在运行,但是在处理 SIGKILL 之前不会处理基于其进程 ID 的新事件。这意味着孩子是前僵尸,行尸走肉,有被贴上标签的危险。
Killing in the process group is different, and is used to kill the siblings, and the parentby the process group #. It's probably also important to note that "killing a process" is not "killing" per se, in the human way, where you expect the process to be destroyed and all memory returned as though it never was. It just sends a particular event, among many, to the process for it to handle. If the process does not handle it properly, then after a while the OS will come along and "clean it up" forcibly.
进程组中的killing不同,用于进程组#杀死兄弟姐妹和父进程。同样重要的是要注意,“杀死一个进程”本身并不是“杀死”,在人性化的方式中,您希望进程被销毁并且所有内存都像从未被销毁一样返回。它只是向进程发送一个特定的事件,在许多事件中进行处理。如果进程没有正确处理它,那么过一段时间操作系统就会出现并强行“清理”。
It (killing) doesn't happen right away because the child (or even the parent) could have written something to disk and be waiting for I/O to complete or doing some other critical task that could compromise system stability or file integrity.
它(杀死)不会立即发生,因为子进程(甚至父进程)可能已将某些内容写入磁盘并等待 I/O 完成或执行一些其他可能危及系统稳定性或文件完整性的关键任务。