subprocess.Popen 之后如何清理?
我有一个长时间运行的 python 脚本,带有一个 perl 工作子进程。数据通过子进程的 stdin 和 stdout 传入和传出。必须定期重新启动子进程。
不幸的是,运行一段时间后,它用完了文件(“打开的文件太多”)。 lsof 显示许多剩余的开放管道。
Popen'd 进程后清理的正确方法是什么?这就是我现在正在做的事情:
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()
I have a long-running python script with a perl worker subprocess. Data is sent in and out of the child proc through its stdin and stdout. Periodically, the child must be restarted.
Unfortunately, after a while of running, it runs out of files ('too many open files'). lsof shows many remaining open pipes.
What's the proper way to clean up after a Popen'd process? Here's what I'm doing right now:
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()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为这就是您所需要的:
据我所知,所有文件对象都将在 popen 进程被终止之前关闭。
I think that's all you need:
As far as I know all file objects will be closed before the popen process gets killed.
一个快速实验表明 x = open("/etc/motd"); x = 1 自行清理并且不留下任何打开的文件描述符。如果您删除对 subprocess.Popen 的最后一个引用,管道似乎会保留下来。您是否有可能重新调用
start_helper()
(甚至其他一些Popen
)而不显式关闭和停止旧的?A quick experiment shows that
x = open("/etc/motd"); x = 1
cleans up after itself and leaves no open file descriptor. If you drop the last reference to asubprocess.Popen
the pipes seem to stick around. Is it possible you are re-invokingstart_helper()
(or even some otherPopen
) without explicitly closing and stopping the old one?