Поскольку ваша программа может ожидать ввода-вывода или иным образом приостановлена. 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 должен сломаться в вашем обработчике сигналов. осмотрите стек. Вы обнаружите, что read все еще ожидает рассмотрения. позвольте обработчику сигнала продолжить и вернуться и посмотреть на результат, возвращаемый write - который будет , затем будет -1.
[1] Естественно, вы напишите свою программу на B на C.: -)