如果父进程退出

时间:2017-08-03 01:35:37

标签: linux bash shell process

我有以下流程树

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

通常如果我终止 test1.sh 进程,子进程 test2.sh sleep 600 将继续运行。但是如果我通过发送信号(SIGSTOP或SIGTSTP)暂停 sleep 600 进程,然后终止 test1.sh 进程,那么 test2.sh sleep 600 将退出。为什么呢?

这是我的测试程序:

test1.sh

#!/bin/sh

./test2.sh

test2.sh

#!/bin/sh

sleep 600

测试步骤:

  1. 运行test1.sh

    $ ./test1.sh

  2. 打开新控制台并暂停子进程。

    $ kill -19<睡眠pid>或者杀死-20<睡眠pid>

  3. 终止父进程test1.sh

    $ kill< test1.sh pid>

  4. 您将找到after step3,test2.sh和sleep 600退出。

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

    任何人都能解释一下吗?非常感谢。

1 个答案:

答案 0 :(得分:1)

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

当进程test2.sh正在运行且其父进程终止时,操作系统会将其移至init进程并继续执行。因此,即使您已杀死test2.sh,结果仍然是sleeptest1.sh进程仍在运行。

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

从GNU手册页:

  

当进程停止时,不再向其发送信号   直到它继续,除了SIGKILL信号和(显然)SIGCONT   信号。信号被标记为待处理,但直到   这个过程还在继续。 SIGKILL信号总是导致终止   的过程,不能被阻止,处理或忽略。您可以   忽略SIGCONT,但它总是导致进程继续   无论如何,如果它被停止。向进程发送SIGCONT信号会导致   要丢弃该进程的任何待处理停止信号。同样,   当进程的任何挂起的SIGCONT信号被丢弃时   收到一个停止信号。

     

孤立进程组中的进程时(请参阅孤立进程   组)接收SIGTSTP,SIGTTIN或SIGTTOU信号,但不接收   处理它,过程不会停止。停止这个过程会   可能不是很有用,因为没有shell程序会   注意它停止并允许用户继续它。反而会发生什么   取决于您使用的操作系统。有些系统可能会这样做   没有;其他人可能会提供另一个信号,例如SIGKILL或   SIGHUP。在GNU / Hurd系统上,该过程随SIGKILL而死;这个   避免了许多停止,孤立的进程的问题   系统。

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