如果脚本完成,子进程(由Popen)有时不想死

时间:2015-12-09 17:30:49

标签: python popen

我注意到有时python不会在Popen和完成脚本之后杀死子进程。

代码:

proc = subprocess.Popen([blablabla_dir + 'blablabla'],
                        stdin=None, stderr=subprocess.STDOUT, stdout=subprocess.PIPE,
                        cwd = None,
                        env = {'LD_LIBRARY_PATH': blablabla_dir + 'lib'})
raise Exception()

结果:

...
    raise Exception()
Exception

但有时候我有:

$ ps aux | grep blablabla
symonen+  2413  0.0  0.1 158572 11988 ?        Sl   19:04   0:00 /home/qqq/dev/eee/build/debug/blablabla
symonen+  2591  0.0  0.0  18636   944 pts/12   S+   19:04   0:00 grep --color=auto blablabla

所以我们有:如果python"有时间"关闭进程(抛出异常后)然后进程完成。如果没有则没有完成

所以问题:是否存在在完成脚本后强制终止所有子进程的方法(例如,脚本运行的某些选项或其他方式)。我正在对我的应用程序进行一些测试,并且在完成我的测试脚本后不希望系统中有垃圾。

我的意思是只有Pyhon的某种方式。所以喜欢"从丛林脚本运行脚本然后杀死丛林脚本中的所有垃圾" - 不合适。

向我发送所有创建的进程信号(15或9)并不是一个好方法。更准确地说,它是一种选择,但它并不能完全解决问题。当然,我通过信号关闭我的应用程序。但是:如果我们在发送kill之前有未处理的异常,那么在脚本完成之后我们将再次拥有垃圾。

2 个答案:

答案 0 :(得分:0)

我有一个可以帮助您解决问题的设计理念。我们将使用一个 spawner python脚本来运行 spawn python脚本。每个spawn脚本运行一个进程并将进程id(pid)返回给spawner。当spawn脚本运行时,sp​​awner被阻塞,一旦spawn脚本完成或失败,spawner就会创建一个调用来杀死它收到的pid。

一些示例代码:

<强>产卵

import shlex
import subprocess
import re

if __name__ == "__main__":

    # Use shlex to make sure your arguments are parsed correctly
    # Here we have the command to run a spawn script
    args = shlex.split("python spawn.py")

    # Run the spawn script
    proc = subprocess.Popen(args,
                            stdout=subprocess.PIPE)

    # Waits for the spawn script to close and receives the output
    spawn_stdout, spawn_err = proc.communicate()

    # Go through the output to find the id of the process spawn started
    match = re.findall(r'(?<=PROCESS_ID)[\d]+?(?=END)', spawn_stdout)

    if len(match) > 0:
        kill = subprocess.Popen("kill {}".format(match[0]),
                                stdout=subprocess.PIPE,
                                shell=True)

<强> 菌种

import subprocess

# We start the process
proc = subprocess.Popen([blablabla_dir + 'blablabla'],
                    stderr=None,
                    stdout=None)

# After it starts, print a unique string containing the process id
print "PROCESS_ID{}END".format(proc.pid)

这是一个有限的设计,我相信你不得不摆弄它,我只是想把它想出来。希望能帮助到你!

答案 1 :(得分:0)

当程序完成时,不要指望子进程被杀死。当解释器关闭时,subprocess和“python”都不会这样做。

执行此操作的正确方法是捕获异常和kill子进程,在finally块中执行此操作。

如果您担心脚本产生的任何其他进程,您可能想要杀死整个进程组

在Linux上,您还可以使用ctypesprctl(2)构建一个非常复杂的解决方案,以确保您的孩子在父母去世时自杀。 (为什么* nix术语总是如此令人毛骨悚然?; - ))