python-如何在测试时可靠地杀死进程?

我有几个不同的脚本,需要打开一个MongoDB实例,如下所示:mongod = Popen([mongod, --dbpath, /path/to/db],)#Do some stuffmongod.terminate()当我正在执行的代码正常工作时,这非常有用,但是当我修改代码时,不...

我有几个不同的脚本,需要打开一个MongoDB实例,如下所示:

mongod = Popen(
        ["mongod", "--dbpath", '/path/to/db'],
    )

#Do some stuff

mongod.terminate()

当我正在执行的代码正常工作时,这非常有用,但是当我修改代码时,不可避免地会出现错误.然后,Mongod实例保持运行状态,下次我尝试运行该脚本时,它将检测到该脚本,并且不会打开新脚本.

我可以从命令行终止该过程,但这有点乏味.或者,我可以将所有内容包装在一个try循环中,但是对于某些脚本,我必须一堆做,因为每个函数都依赖于另一个函数.有没有更优雅的方法即使在代码中其他地方出现错误时也可以强制关闭进程?

编辑:基于tdelaney的注释进行了一些测试,看起来当我在Sublime文本中运行这些脚本并生成错误时,该脚本实际上并未完成-它遇到错误,然后等待mongod实例打开…我认为.一旦我在终端中终止了该进程,崇高的文字就会告诉我“在X秒内使用退出代码1完成

编辑2:在柯比的建议下,尝试:

def testing():   
    mongod = Popen(
            ["mongod", "--dbpath", '/Users/KBLaptop/computation/db/'],
        )

    #Stuff that generates error

    mongod.terminate()

def cleanup():
    for proc in subprocess._active[:]:
        try: proc.terminate()
        except: pass

atexit.register(cleanup)
testing()

testing()中的错误似乎阻止了任何事情的继续,因此atexit从未注册,并且进程一直在运行.我是否缺少明显的东西?

解决方法:

如果您在CPython下运行,则可以作弊并利用Python的析构函数:

class PopenWrapper(object):
    def __del__(self):
        if self._child_created:
            self.terminate()

不过,这有点令人讨厌.我的首选是退出:

import atexit
mongod = Popen(...)
def cleanup():
    for proc in subprocess._active[:]:
        try: proc.terminate()
        except: pass
atexit.register(cleanup)

不过,仍然有点破烂.

编辑:试试这个:

from subprocess import Popen
import atexit

started = []

def auto_popen(*args, **kw):
    p = Popen(*args, **kw)
    started.append(p)
    return p

def testing():
    mongod = auto_popen(['blah blah'], shell=True)
    assert 0

    #Stuff that generates error

    mongod.terminate()

def cleanup():
    for proc in started:
        if proc.poll() is None:
            try: proc.kill()
           except: pass

atexit.register(cleanup)
testing()

本文标题为:python-如何在测试时可靠地杀死进程?

基础教程推荐