Kill -9 $PPID 杀死进程吗?

Kill -9 $PPID 杀死进程吗?

我读到杀死父进程将使子进程附加到 init (PPID=1)。

为了测试这一点,我创建了三个 shell 并向第二个 shell 发送了终止信号:

# first process "a"
a$sh
# second process "b"
sh-5.0$ PS1=b$
b$sh
# thrid process "c"
sh-5.0$ PS1=c$
# killing process "b"
c$kill -9 $PPID
c$Killed
a$exit
a$

(killed和exit打印到屏幕上,而不是输入)

但第三个 shell 也被杀死,而不是附加到 init 上。为什么以及由谁执行?

答案1

我将重新创建你的实验:

# First shell
$ echo $$
41903

# Start the second shell
$ bash
$ echo $$ $PPID
41934 41903

# Start the third shell
$ bash
$ echo $$ $PPID
41938 41934

现在,在第二个终端中,我将用来strace监视第三个 shell 执行的系统调用和处理的信号。请注意,shell 被阻塞等待输入:

$ strace -p 41938
strace: Process 41938 attached
pselect6(1, [0], NULL, NULL, NULL, {[], 8}) = 1 (in [0])

在第三个终端中,我将杀死第二个 shell(我正在跟踪的 shell 的父 shell):

$ kill -9 41934

这时我观察到没有什么strace输出中——第三个 shell 仍在运行。

现在,如果我尝试在第一个终端中输入某些内容,我会在输出中看到以下内容strace

read(0, 0x7ffd6879ebbf, 1)              = -1 EIO (Input/output error)
...
write(2, "exit\n", 5)                   = 5
...
setpgid(0, 41938)                       = 0
exit_group(0)                           = ?

第三个 shell 无法从标准输入(文件描述符 0——read本例中的第一个参数)读取数据并自行终止。终止父进程似乎以某种方式改变了终端设备的状态,导致read()子进程失败。

让我们重复这个实验,但这次跟踪第一个 shell——我要杀死的进程的父进程。

$ echo $$
48134

$ bash
$ echo $$ $PPID
48163 48134

$ bash
$ echo $$ $PPID
48169 48163

在单独的终端中,跟踪第一个 shell:

$ strace -p 48134
strace: Process 48134 attached
wait4(-1, 

在另一个终端中,杀死第二个 shell:

$ kill -9 48163

最初的贝壳对于它的孩子的死亡做了什么反应?

wait4(-1, [{WIFSIGNALED(s) && WTERMSIG(s) == SIGKILL}], WSTOPPED|WCONTINUED, NULL) = 48163
rt_sigprocmask(SIG_BLOCK, [CHLD TSTP TTIN TTOU], [CHLD], 8) = 0
ioctl(255, TIOCSPGRP, [48134])          = 0

ioctl()请注意带有参数的调用TIOCSPGRP。当第一个 shell 注意到其子进程终止时,它将终端的前台进程组 ID 更改回其自身(请注意,fd 255 也是终端设备的打开文件描述符)。这就是导致read()第三个 shell 失败的原因 - 它尝试从设备读取,但不在前台进程组中。

相关内容