Python 如何在subprocess.Popen之后进行清理?
我有一个长时间运行的python脚本和一个perl worker子进程。数据通过其stdin和stdout进出子进程。必须定期重新启动子级 不幸的是,运行一段时间后,它的文件用完了(“打开的文件太多”)。lsof显示了许多剩余的开放管道 什么是正确的方法来清理后的Popen'd的过程?以下是我现在正在做的:Python 如何在subprocess.Popen之后进行清理?,python,subprocess,pipe,popen,lsof,Python,Subprocess,Pipe,Popen,Lsof,我有一个长时间运行的python脚本和一个perl worker子进程。数据通过其stdin和stdout进出子进程。必须定期重新启动子级 不幸的是,运行一段时间后,它的文件用完了(“打开的文件太多”)。lsof显示了许多剩余的开放管道 什么是正确的方法来清理后的Popen'd的过程?以下是我现在正在做的: def start_helper(self): # spawn perl helper cwd = os.path.dirname(__file__) if not
def start_helper(self):
# spawn perl helper
cwd = os.path.dirname(__file__)
if not cwd:
cwd = '.'
self.subp = subprocess.Popen(['perl', 'theperlthing.pl'], shell=False, cwd=cwd,
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
bufsize=1, env=perl_env)
def restart_helper(self):
# clean up
if self.subp.stdin:
self.subp.stdin.close()
if self.subp.stdout:
self.subp.stdout.close()
if self.subp.stderr:
self.subp.stderr.close()
# kill
try:
self.subp.kill()
except OSError:
# can't kill a dead proc
pass
self.subp.wait() # ?
self.start_helper()
快速实验表明,
x=open(“/etc/motd”);x=1
会在其自身之后进行清理,并且不会留下任何打开的文件描述符。如果删除对subprocess.Popen的最后一个引用,管道似乎会粘住。您是否可以在不明确关闭和停止旧的帮助程序的情况下重新调用start\u helper()
def restart_helper(self):
# kill the process if open
try:
self.subp.kill()
except OSError:
# can't kill a dead proc
pass
self.start_helper()
# the wait comes after you opened the process
# if you want to know how the process ended you can add
# > if self.subp.wait() != 0:
# usually a process that exits with 0 had no errors
self.subp.wait()
据我所知,所有文件对象都将在popen进程终止之前关闭。popen.kill
(或popen.terminate
)是您最好的选择。当您终止它时,除了已经死了之外,它还会因为其他原因引发操作系统错误吗?子流程中有一个稍微不相关的错误,但它可能会对\u cleanup()
使用close\u fds=True
(py3k上的默认值)有所帮助,如果您不在Windowsbtw上,在某些系统上,打开文件的数量限制非常小。wait()是不让子进程和打开管道掉队的关键。我认为这最终是正确的。