Estoy leyendo la documentación de Python en la clase de Popen en la sección del módulo de subproceso y encontré el siguiente código:
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]
La documentación también establece que
“La llamada p1.stdout.close () después de iniciar p2 es importante para que p1 reciba un SIGPIPE si p2 sale antes de p1.
¿Por qué se debe cerrar p1.stdout antes de que podamos recibir un SIGPIPE y cómo p1 sabe que p2 sale antes de p1 si ya lo hemos cerrado?
SIGPIPE
es una señal que se enviaría si dmesg
intentara escribir en un conducto cerrado. Aquí, dmesg
termina con dos destinos para escribir, su proceso Python y el proceso grep
.
Esto se debe a que el archivo de clones de subprocess
se maneja (mediante la función os.dup2()
). La configuración de p2
para usar p1.stdout
desencadena una llamada os.dup2()
que solicita al sistema operativo que duplique el p1.stdout
os.dup2()
tubería; el duplicado se utiliza para conectar dmesg
a grep
.
Con dos manejadores de archivo abiertos para dmesg
stdout, a dmesg
nunca se le da una señal SIGPIPE
si solo uno de ellos se cierra antes, por lo que el cierre de grep
nunca se detectaría. dmesg
seguiría produciendo innecesariamente.
Entonces, al cerrar p1.stdout
inmediatamente, se asegura de que la única lectura de dmesg
restante de dmesg
stdout sea el proceso grep
, y si ese proceso fuera a salir, dmesg
recibe un SIGPIPE
.