如果父进程退出,则挂起subprocess退出

我有以下过程树

test1.sh \- test2.sh \- sleep 600 

通常如果我杀了test1.sh进程,subprocesstest2.shsleep 600将继续运行。 但是,如果我通过发送信号(SIGSTOP或SIGTSTP)暂停睡眠600进程,然后杀死test1.sh进程,则test2.shsleep 600将退出。 为什么?

这是我的testing程序:

test1.sh

 #!/bin/sh ./test2.sh 

test2.sh

 #!/bin/sh sleep 600 

testing步骤:

  1. 运行test1.sh

    $ ./test1.sh

  2. 打开新的控制台并暂停subprocess。

    $ kill -19 <sleep pid>或杀死-20 <sleep pid>

  3. 杀死父进程test1.sh

    $ kill <test1.sh pid>

你会发现步骤3之后,test2.sh和sleep 600退出。

错误,如果我只运行step1和step3,忽略step2,test2.sh和睡眠600进程将不会退出。

任何人都可以解释吗? 非常感谢。

当你杀死进程test1.sh ,你离开test2.sh孤儿,所以你需要知道你的操作系统中的孤儿进程会发生什么。

当进程test2.sh正在运行,并且他的父母死亡时,OS将其移动到init进程并保持其执行。 所以结果是,即使你杀了test1.shtest2.shsleep进程仍然是up的。

当进程sleep停止(信号20)和他的父母死亡时,操作系统尝试将其移动到init进程。 但是,由于进程停止,并且不再有任何tty能够恢复(因为其父母已经死亡),操作系统可能会决定在进程中做其他事情。 在你的情况下,它死亡与SIGKILL,以避免许多停止,孤立的进程周围的系统的问题。 由于sleep过程已经退出, test2.sh过程也结束了。

从GNU手册页:

当一个进程停止时,除SIGKILL信号和(明显)SIGCONT信号之外,不会有更多的信号传递给它。 信号被标记为挂起,但是直到该过程继续才被传送。 SIGKILL信号总是导致进程终止,不能被阻塞,处理或忽略。 你可以忽略SIGCONT,但是如果它停止的话总是会导致进程继续。 发送一个SIGCONT信号给进程会导致该进程的任何挂起的停止信号被丢弃。 同样,任何正在处理的SIGCONT信号在接收到停止信号时都会被丢弃。

当孤立进程组中的进程(请参见孤立进程组)收到SIGTSTP,SIGTTIN或SIGTTOU信号并且不处理它时,进程不会停止。 停止进程可能不会很有用,因为没有shell程序会注意到它停止并允许用户继续它。 发生什么反而取决于您正在使用的操作系统。 有些系统可能无能为力; 其他人可能会传递另一个信号,如SIGKILL或SIGHUP。 在GNU / Hurd系统上,进程与SIGKILL一起死掉; 这避免了许多停止的问题,孤立的进程躺在系统周围。

顺便说一下,如果你愿意杀死他们,你总是可以在主进程中添加一个trap来捕获信号并正确地退出子进程。