Поскольку ваша программа может ожидать ввода-вывода или иным образом приостановлена. SIGPIPE асинхронно прерывает вашу программу, прерывая системный вызов, и поэтому может быть обработан немедленно.
Обновить
Рассмотрим трубопровод A | B | C
.
Для определенности предположим, что B - это канонический цикл копирования:
while((sz = read(STDIN,bufr,BUFSIZE))>=0)
write(STDOUT,bufr,sz);
B
блокируется при вызове read (2), ожидающем данных с A
момента C
завершения. Если вы дождетесь кода возврата от write (2) , когда B его увидит? Ответ, конечно, не будет до тех пор, пока A не запишет больше данных (что может занять долгое время - что, если A заблокирован чем-то другим?). Заметьте, кстати, что это также позволяет нам более простую и чистую программу. Если вы зависели от кода ошибки при записи, вам понадобится что-то вроде:
while((sz = read(STDIN,bufr,BUFSIZE))>=0)
if(write(STDOUT,bufr,sz)<0)
break;
Еще одно обновление
Ага, вы запутались в поведении пишите. Видите ли, когда дескриптор файла с ожидающей записью закрывается, сразу же происходит SIGPIPE. Пока запись вернет -1 конечном итоге , весь смысл сигнала состоит в том, чтобы асинхронно уведомить вас о том, что запись больше невозможна. Это часть того, что заставляет всю элегантную структуру совместных подпрограмм работать в UNIX.
Теперь я мог бы указать вам на целое обсуждение в любой из нескольких книг по системному программированию UNIX, но есть лучший ответ: вы можете проверить это сами. Напишите простую B
программу [1] - у вас уже есть смелость, все, что вам нужно, это main
и некоторые включает - и добавьте обработчик сигнала для SIGPIPE
. Запустите конвейер как
cat | B | more
а в другом окне терминала подключите отладчик к B и поместите точку останова в обработчик сигнала B.
Теперь убейте больше, и B должен сломать ваш обработчик сигналов. изучить стек. Вы обнаружите, что чтение еще не завершено. позвольте обработчику сигнала продолжить и вернуться, и посмотрите на результат, возвращаемый записью, который тогда будет -1.
[1] Естественно, вы будете писать свою программу B на C. :-)
write
.