我有几个不同的脚本需要打开一个类似这样的MongoDB实例:
mongod = Popen(
["mongod", "--dbpath", '/path/to/db'],
)
#Do some stuff
mongod.terminate()
当我执行的代码工作时,这很有效,但是当我修补时,错误不可避免地会出现。然后Mongod实例仍在运行,下次我尝试运行该脚本时,它会检测到并且不会打开一个新脚本。
我可以从命令行终止进程,但这有点单调乏味。或者我可以在try
循环中包装所有内容,但是对于某些脚本,我必须这样做,因为每个函数都依赖于其他每个函数。即使在代码中的其他地方发生错误,是否有更优雅的方法强制关闭进程?
"finished in X seconds with exit code1"
EDIT2:关于柯比的建议,尝试过:
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
永远不会注册,并且进程会继续运行。我错过了一些明显的东西吗?
答案 0 :(得分:3)
如果你在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()