При каких условиях подпроцесс Python получает SIGPIPE?

Я читаю документацию по Python для класса Popen в разделе модуля подпроцесса и наткнулся на следующий код:

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]

В документации также говорится, что

"Вызов p1.stdout.close() после запуска p2 важен для того, чтобы p1 получил SIGPIPE, если p2 выходит до p1.

Почему p1.stdout должен быть закрыт до того, как мы сможем получить SIGPIPE, и как p1 знает, что p2 выходит до p1, если мы уже закрыли его?

1 ответ

Решение

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

Это потому что subprocess дескрипторы файла клонов (используя os.dup2() функция). Настройка p2 использовать p1.stdout запускает os.dup2() вызов, который просит ОС дублировать дескриптор файла канала; дубликат используется для подключения dmesg в grep,

С двумя открытыми файловыми ручками для dmesg стандартный вывод, dmesg никогда не дают SIGPIPE сигнал, если только один из них закрывается рано, так grep закрытие никогда не будет обнаружено. dmesg будет без необходимости продолжать производить продукцию.

Итак, закрыв p1.stdout немедленно, вы гарантируете, что единственное оставшееся чтение файлового дескриптора из dmesg стандартный вывод grep процесс, и если этот процесс должен был выйти, dmesg получает SIGPIPE,

Другие вопросы по тегам