Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在测试时可靠地终止进程?_Python_Mongodb - Fatal编程技术网

Python 如何在测试时可靠地终止进程?

Python 如何在测试时可靠地终止进程?,python,mongodb,Python,Mongodb,我有两个不同的脚本需要打开MongoDB实例,如下所示: mongod = Popen( ["mongod", "--dbpath", '/path/to/db'], ) #Do some stuff mongod.terminate() 当我正在执行的代码工作时,这非常有效,但是当我在修补时,不可避免地会出现错误。然后Mongod实例仍在运行,下次我尝试运行脚本时,它会检测到这一点,并且不会打开新实例 我可以从命令行终止进程,但这有点乏味。或者,我可以将所有内容包

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

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

#Do some stuff

mongod.terminate()
当我正在执行的代码工作时,这非常有效,但是当我在修补时,不可避免地会出现错误。然后Mongod实例仍在运行,下次我尝试运行脚本时,它会检测到这一点,并且不会打开新实例

我可以从命令行终止进程,但这有点乏味。或者,我可以将所有内容包装在
try
循环中,但对于某些脚本,我必须执行大量操作,因为每个函数都依赖于其他函数。是否有一种更优雅的方法,即使在代码中的其他地方发生错误时,也可以强制关闭进程

编辑:根据tdelaney的评论做了一些测试,看起来当我在Sublime文本中运行这些脚本并生成en错误时,脚本实际上并没有完成-它遇到错误,然后等待mongod实例打开。。。我想。一旦我在终端中终止进程,升华文本告诉我“退出代码1,在X秒内完成”

编辑2:根据Kirby的建议,尝试:

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()
不过,这有点不吉利。我倾向于
atexit

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()

您可以维护活动进程的全局列表,并注册杀死它们的
atexit
处理程序。你甚至可以用一个新的
Popen
来修改
子进程
。@tdelaney你愿意详细说明一下吗?我还是个新手。查看了
atexit
的文档,看起来这将是正确的调用,但并不真正理解如何实现它。我尝试将上述代码放入函数中并调用
atexit.register(func())
,也只是将
atexit.register(mongod)
放在脚本末尾,或者
atexit.register(mongod.terminate())
。。。很明显,我不明白它在做什么。@t事实上,也许退欧不是最好的方式。。。请参阅第二位代码中的“我的编辑”(简短版本:脚本似乎会吐出错误,但在我在终端中杀死它之前不会真正退出),atexit在哪里?刚刚尝试了第二部分-我遇到了与上面编辑中相同的问题。也就是说,这个过程永远不会结束。无论是在原始函数之后调用
cleanup()
,还是执行
atexit.register(cleanup())
,代码都不会到达cleanup函数,因此进程保持打开状态。我没有在CPython下运行,至少据我所知不是这样。@kevbonham您应该在不调用函数的情况下传递函数。另外,如果您的Python没有说IronPython、PyPy或Jython,那么您使用的是CPython。它没有明确地说CPython。啊,明白了-谢谢你的解释。不幸的是,这似乎无法解决问题,请参见我的编辑2。@kevbonham Ack,我想我将if语句写反了。如果proc.poll()为None,请尝试