Почему close_fds = False иногда зависает процесс в Python 2? - PullRequest
1 голос
/ 17 апреля 2019

Я заметил, что в подпроцессах Python3 значение по умолчанию для параметра Popen close_fds было изменено с False на True, и я подумал, что было причиной и является ли это хорошей практикой для почти всегда установите close_fds на True (так как я все еще использую Python 2.7).

Я нашел ссылку, показывающую проблему с close_fds=False.

https://bugs.python.org/issue7213

К сожалению, мне непонятно, почему так происходит.

import subprocess as sub
p1 = sub.Popen(['cat'], stdin=sub.PIPE, stdout=sub.PIPE, close_fds=False)
p2 = sub.Popen(['grep', 'a'], stdin=p1.stdout, stdout=sub.PIPE, close_fds=False)
p1.stdin.write("aaaaaaaaaaaaaaaa\n")
p1.stdin.close()
p2.stdout.read()  # Hangs on Python 2

Программа зависает на Python2, отсутствует на Python3 и вообще не зависает, если для close_fds установлено значение True. Так что мне интересно ... Что там было на самом деле?

РЕДАКТИРОВАТЬ: Он висит на моем Python 2.6 и перестал зависать на 2.7

1 Ответ

2 голосов
/ 23 апреля 2019

Что там было на самом деле?

В Python 2.6 дескриптор файла конца записи канала p1.stdin наследуется p2, что не имеет значенияили знать об этом и поэтому оставляет его открытым.Следовательно, хотя родительский процесс выполняет p1.stdin.close(), канал записи остается открытым, и поэтому cat не обнаруживает EOF на своем входе и продолжает ожидать данные из канала, блокируя всю цепочку процессов.

В Python 2.7 вызовы fcntl(…, F_SETFD, FD_CLOEXEC) следуют за созданием каналов stdin и stdout, так что конец канала записи не наследуется p2 и фактически закрывается p1.stdin.close().

...