如何正确杀死应用程序启动的所有进程?

时间:2017-09-12 13:19:45

标签: python kill-process

我们有一个用Python编写的大型应用程序。我们希望在关闭或中断应用程序时干净地杀死应用程序启动的进程。但是,通过Python代码(例如subprocess.Popen或os.system),我们有一个命令 A ,它启动另一个子命令 B ,但命令 B 似乎与命令 A 无关。命令 B 的父进程是init进程(使用pid 1)。如何在Python代码中终止进程 B (例如在Ctrl + C之后)?

例如,我们有2个shell脚本和一个调用这些shell脚本的Python脚本。

第一个Shell脚本 mycommand1.sh 是:

#!/bin/sh
sleep 3600 &

第二个Shell脚本 mycommand2.sh 是:

#!/bin/sh
sleep 3600

Python脚本 myscript.py 是:

import os
import signal
import subprocess

def launchCommands():

    proc1 = subprocess.Popen('./mycommand1.sh', stdout=subprocess.PIPE, shell = True, preexec_fn=os.setsid)
    print "the processus 1 has started"

    proc2 = subprocess.Popen('./mycommand2.sh', stdout=subprocess.PIPE, shell = True, preexec_fn=os.setsid)
    print "the processus 2 has started"

    return proc1, proc2


if __name__ == '__main__':
    proc1 = None
    proc2 = None
    try:
        proc1, proc2 = launchCommands()
        while True:
            pass

    except KeyboardInterrupt:
        print "Ctrl+C received! ..."

        print "trying to kill the processus 2"
        os.killpg(os.getpgid(proc2.pid), signal.SIGTERM)
        print "processus 2 has been killed"

        print "trying to kill the processus 1"
        os.killpg(os.getpgid(proc1.pid), signal.SIGTERM)
        print "processus 1 has been killed"

然后我们执行Python脚本,然后用Ctrl + C在3秒后中断它。 这是中断后的输出。

$> python myscript.py
the processus 1 has started
the processus 2 has started
^CCtrl+C received! ...
trying to kill the processus 2
processus 2 has been killed
trying to kill the processus 1
Traceback (most recent call last):
File "myscript.py", line 33, in <module>
  os.killpg(os.getpgid(proc1.pid), signal.SIGTERM)
OSError: [Errno 3] No such process

我们在执行Python脚本的同时和之后显示所有“睡眠”进程(当然,在执行Python脚本之前没有睡眠过程)。

运行myscript.py命令时:

$> ps -ef | grep sleep
  501 50700     1   0  2:21   ??         0:00.00 sleep 3600
  501 50701 50699   0  2:21   ??         0:00.00 sleep 3600
  501 50703   410   0  2:21   ttys002    0:00.00 grep sleep

用Ctrl + C中断程序后:

$> ps -ef | grep sleep
  501 50700     1   0  2:21   ??         0:00.00 sleep 3600
  501 51025   410   0  2:23   ttys002    0:00.00 grep sleep

正如我们所看到的,我们尝试杀死的进程1不再存在,并且父进程为1的进程休眠始终存在。此进程睡眠来自脚本mycommand1.sh的执行。如何正确杀死这个进程睡眠脚本myscript.py(当然,我们不希望杀死所有的睡眠过程)?

1 个答案:

答案 0 :(得分:0)

尝试重写mycommand1.sh

#!/bin/sh
foo(){
    cnt=0
    while [ $cnt -le 100 ]; do
        cnt=$((cnt+1))
        echo $0 $cnt
        sleep 1
    done
}

foo &

mycommand2.sh

#!/bin/sh
foo(){
    cnt=0
    while [ $cnt -le 100 ]; do
        cnt=$((cnt+1))
        echo $0 $cnt
        sleep 1
    done
}

foo

stdout=subprocess.PIPE移除myscript.py 检查一下。