Porque su programa puede estar esperando E / S o suspendido. Un SIGPIPE interrumpe su programa de forma asincrónica, terminando la llamada al sistema y, por lo tanto, puede manejarse de inmediato.
Actualizar
Considere una tubería A | B | C
.
Para ser precisos, asumiremos que B es el ciclo de copia canónico:
while((sz = read(STDIN,bufr,BUFSIZE))>=0)
write(STDOUT,bufr,sz);
B
está bloqueado en la llamada read (2) en espera de datos desde el A
momento en que C
finaliza. Si espera el código de retorno de write (2) , ¿cuándo lo verá B? La respuesta, por supuesto, no es hasta que A escriba más datos (lo que podría ser una larga espera, ¿qué pasa si A está bloqueado por otra cosa?). Observe, por cierto, que esto también nos permite un programa más simple y limpio. Si dependía del código de error de escritura, necesitaría algo como:
while((sz = read(STDIN,bufr,BUFSIZE))>=0)
if(write(STDOUT,bufr,sz)<0)
break;
Otra actualización
Ajá, estás confundido sobre el comportamiento de la escritura. Verá, cuando el descriptor de archivo con la escritura pendiente se cierra, el SIGPIPE ocurre en ese momento. Si bien la escritura devolverá -1 eventualmente , el objetivo de la señal es notificarle de forma asincrónica que la escritura ya no es posible. Esto es parte de lo que hace que toda la elegante estructura de co-rutina de las tuberías funcione en UNIX.
Ahora, podría señalarle una discusión completa en cualquiera de los varios libros de programación del sistema UNIX, pero hay una mejor respuesta: puede verificarlo usted mismo. Escriba un B
programa simple [1] - ya tiene las agallas, todo lo que necesita es un main
y algunos incluyen - y agregue un controlador de señal para SIGPIPE
. Ejecutar una tubería como
cat | B | more
y en otra ventana de terminal, adjunte un depurador a B y coloque un punto de interrupción dentro del manejador de señal B.
Ahora, mata más y B debería entrar en tu manejador de señales. examine la pila. Verá que la lectura aún está pendiente. deje que el manejador de señales proceda y regrese, y observe el resultado devuelto por write , que luego será -1.
[1] Naturalmente, escribirás tu programa B en C. :-)
write
.