Weil Ihr Programm möglicherweise auf E / A wartet oder auf andere Weise angehalten wird. Ein SIGPIPE unterbricht Ihr Programm asynchron, beendet den Systemaufruf und kann so sofort verarbeitet werden.
Aktualisieren
Betrachten Sie eine Pipeline A | B | C
.
Nur zur Bestimmtheit nehmen wir an, dass B die kanonische Kopierschleife ist:
while((sz = read(STDIN,bufr,BUFSIZE))>=0)
write(STDOUT,bufr,sz);
B
wird beim Aufruf von read (2) blockiert und wartet auf Daten ab dem A
Zeitpunkt der C
Beendigung. Wenn Sie auf den Rückkehrcode von write (2) warten , wann wird B ihn sehen? Die Antwort ist natürlich erst, wenn A mehr Daten schreibt (was eine lange Wartezeit sein kann - was ist, wenn A durch etwas anderes blockiert wird?). Beachten Sie übrigens, dass dies uns auch ein einfacheres und saubereres Programm ermöglicht. Wenn Sie beim Schreiben auf den Fehlercode angewiesen wären, benötigen Sie Folgendes:
while((sz = read(STDIN,bufr,BUFSIZE))>=0)
if(write(STDOUT,bufr,sz)<0)
break;
Ein weiteres Update
Aha, du bist verwirrt über das Verhalten des Schreibens. Sie sehen, wenn der Dateideskriptor mit dem ausstehenden Schreibvorgang geschlossen wird, geschieht das SIGPIPE sofort. Während der Schreibvorgang schließlich -1 zurückgibt , besteht der Sinn des Signals darin, Sie asynchron zu benachrichtigen, dass der Schreibvorgang nicht mehr möglich ist. Dies ist Teil dessen, was die gesamte elegante Co-Routine-Struktur von Pipes unter UNIX zum Funktionieren bringt.
Jetzt könnte ich Sie auf eine ganze Diskussion in einem der verschiedenen UNIX-Systemprogrammierbücher hinweisen, aber es gibt eine bessere Antwort: Sie können dies selbst überprüfen. Schreiben Sie ein einfaches B
Programm [1] - Sie haben bereits den Mut, alles, was Sie brauchen, ist ein main
und einige enthält - und fügen Sie einen Signalhandler für hinzu SIGPIPE
. Führen Sie eine Pipeline wie aus
cat | B | more
Fügen Sie in einem anderen Terminalfenster einen Debugger an B hinzu und setzen Sie einen Haltepunkt in den B-Signalhandler.
Töte jetzt mehr und B sollte deinen Signalhandler einbrechen. Untersuche den Stapel. Sie werden feststellen, dass der Lesevorgang noch aussteht. Lassen Sie den Signalhandler fortfahren und zurückkehren und sehen Sie sich das vom Schreiben zurückgegebene Ergebnis an - das dann -1 ist.
[1] Natürlich schreibst du dein B-Programm in C. :-)
write
.