Как очистить после subprocess.Popen?
У меня длинный python script с подпроцессом work 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()
Ответы
Ответ 1
Я думаю, что все, что вам нужно:
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 будет убит.
Ответ 2
Быстрый эксперимент показывает, что x = open("/etc/motd"); x = 1
очищается после себя и не оставляет открытого дескриптора файла. Если вы отбрасываете последнюю ссылку на subprocess.Popen
, трубы, похоже, остаются. Возможно ли, что вы повторно вызываете start_helper()
(или даже некоторые другие Popen
) без явного закрытия и остановки старого?