закрытие stdout конвейерного подпроцесса Python - PullRequest
13 голосов
/ 12 сентября 2011

Вот что я могу прочитать в документации к модулю подпроцесса python:

Replacing shell pipeline

    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]

The p1.stdout.close() call after starting the p2 is important in order for p1
to receive a SIGPIPE if p2 exits before p1.

Я не очень понимаю, почему мы должны закрыть p1.stdout после того, как создали p2. Когда точно выполняется p1.stdout.close ()? Что происходит, когда p2 никогда не заканчивается? Что происходит, когда ни p1, ни p2 заканчиваются?

Ответы [ 2 ]

15 голосов
/ 12 сентября 2011

Из Википедия , SIGPIPE - это сигнал, отправляемый процессу, когда он пытается записать в канал без процесса, подключенного к другому концу.

Когда вы впервые создаете p1, используя stdout=PIPE, к каналу подключен один процесс, который является вашим процессом Python, и вы можете прочитать вывод, используя p1.stdout.

Когда вы создаете p2 с использованием stdin=p1.stdout, теперь к каналу подключены два процесса p1.stdout.

Обычно, когда вы запускаете процессы в конвейере, вы хотите, чтобы все процессы заканчивались, когда заканчивался какой-либо из процессов. Чтобы это произошло автоматически, вам нужно закрыть p1.stdout, поэтому p2.stdin - единственный процесс, присоединенный к этому каналу, таким образом, если p2 заканчивается и p1 записывает дополнительные данные в стандартный вывод, он получит SIGPIPE, так как есть больше нет процессов, связанных с этим каналом.

1 голос
/ 12 сентября 2011

Хорошо, я вижу. p1.stdout закрыт из моего скрипта на python, но остается открытым в p2, а затем p1 и p2 связываются вместе. За исключением случаев, когда p2 уже закрыт, тогда p1 получает SIGPIPE. Я прав?

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