При каких условиях подпроцесс 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
,