Объяснить пример конвейера из модуля подпроцесса Python - PullRequest
7 голосов
/ 18 мая 2011

Раздел 17.1.4.2: Замена конвейера оболочки модуля подпроцесса python говорит о замене

output=`dmesg | grep hda`

с

p1 = Popen(["dmesg"], stdout=PIPE)
p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
p1.stdout.close()  # Allow p1 to receive a SIGPIPE if p2 exits.
output = p2.communicate()[0]

Комментарий к третьей строке объясняет, почему вызывается функция close, а не почему она имеет смысл. Это не для меня. Не помешает ли закрытие p1.stdout до вызова метода связи предотвратить любой вывод через канал? (Очевидно, что нет, я попытался запустить код, и он работает нормально). Почему необходимо вызвать close, чтобы p1 получил SIGPIPE? Что это за закрытие? Что именно это закрывает?

Пожалуйста, сочтите это академическим вопросом, я не пытаюсь достичь ничего, кроме лучшего понимания этих вещей.

1 Ответ

10 голосов
/ 18 мая 2011

Вы закрываете p1.stdout в процессе parent , таким образом, dmesg остается единственным процессом с открытым дескриптором файла. Если вы этого не сделаете, даже когда dmesg закроет свой стандартный вывод, он все равно останется открытым, и SIGPIPE не будет сгенерировано. (ОС в основном ведет подсчет ссылок и генерирует SIGPIPE, когда он достигает нуля. Если вы не закроете файл, вы предотвратите его достижение до нуля.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...