Как очистить после подпроцесса. Открыть? - PullRequest
15 голосов
/ 17 февраля 2011

У меня есть долго работающий скрипт на python с рабочим подпроцессом perl. Данные отправляются в и из дочернего процесса через его стандартный ввод и стандартный вывод. Периодически ребенок должен быть перезапущен.

К сожалению, через некоторое время работы у него заканчиваются файлы («слишком много открытых файлов»). 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()

Ответы [ 2 ]

6 голосов
/ 29 марта 2011

Я думаю, это все, что вам нужно:

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.

1 голос
/ 01 марта 2011

Быстрый эксперимент показывает, что x = open("/etc/motd"); x = 1 очищается после себя и не оставляет дескриптора открытого файла.Если вы отбросите последнюю ссылку на subprocess.Popen, то трубы, похоже, останутся.Возможно ли, что вы повторно вызываете start_helper() (или даже какой-то другой Popen) без явного закрытия и остановки старого?

...