subprocess.Popen 之后如何清理?

发布于 2024-10-18 02:14:00 字数 932 浏览 8 评论 0原文

我有一个长时间运行的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

秋意浓 2024-10-25 02:14:00

我认为这就是您所需要的:

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 进程被终止之前关闭。

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.

指尖微凉心微凉 2024-10-25 02:14:00

一个快速实验表明 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 a subprocess.Popen the pipes seem to stick around. Is it possible you are re-invoking start_helper() (or even some other Popen) without explicitly closing and stopping the old one?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文