15

私はperlワーカーサブプロセスを備えた長時間実行のPythonスクリプトを持っています。データは、stdinおよびstdoutを介して子プロシージャに送受信されます。定期的に、子を再起動する必要があります。

残念ながら、しばらく実行すると、ファイルが不足します(「開いているファイルが多すぎます」)。lsofは、多くの開いているパイプを示しています。

Popenされたプロセスの後にクリーンアップする適切な方法は何ですか?これが私が今していることです:

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

2 に答える 2

7

必要なのはそれだけだと思います:

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 プロセスが強制終了される前に閉じられます。

于 2011-03-29T01:55:38.373 に答える
1

簡単な実験は、x = open("/etc/motd"); x = 1それ自体がクリーンアップされ、開いているファイル記述子を残さないことを示しています。a への最後の参照を削除するとsubprocess.Popen、パイプがくっついているように見えます。古いものを明示的に閉じたり停止したりせずにstart_helper()、(または他の) を再呼び出ししている可能性はありますか?Popen

于 2011-03-01T08:25:05.063 に答える