简体   繁体   English

subprocess.Popen后如何清理?

[英]How to clean up after subprocess.Popen?

I have a long-running python script with a perl worker subprocess. 我有一个长期运行的python脚本与perl worker子进程。 Data is sent in and out of the child proc through its stdin and stdout. 数据通过stdin和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. lsof显示了许多剩余的开放管道。

What's the proper way to clean up after a Popen'd process? 在Popen'd过程之后清理的正确方法是什么? 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()

I think that's all you need: 我认为这就是你所需要的:

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

As far as I know all file objects will be closed before the popen process gets killed. 据我所知,所有文件对象将在popen进程被杀死之前关闭。

A quick experiment shows that x = open("/etc/motd"); x = 1 一个快速实验表明x = open("/etc/motd"); x = 1 x = open("/etc/motd"); x = 1 cleans up after itself and leaves no open file descriptor. x = open("/etc/motd"); x = 1自行清理并且不保留打开的文件描述符。 If you drop the last reference to a subprocess.Popen the pipes seem to stick around. 如果你删除最后一个subprocess.Popen引用管道似乎坚持。 Is it possible you are re-invoking start_helper() (or even some other Popen ) without explicitly closing and stopping the old one? 难道你重新调用start_helper()或者甚至一些其他Popen )没有明确的关,停旧的?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM