To kaprysy planowania.
Twój producent - nazwijmy to alphabeta
- jest w stanie pracować przez pewien czas przed head
kwota jest w stanie odczytać i exit (łamiąc w ten sposób rury).
To "pewna ilość czasu", oczywiście, jest zmienna.
Czasami alphabeta
działa 20 razy, zanim head
może odczytać stdin i wyjść. Czasami 200 razy. W moim systemie czasami 300 lub 1000 lub 2000 razy. W rzeczywistości może teoretycznie zapętlić się do wydajności rury łączącej producenta i konsumenta.
Do demonstracji, niech wprowadzają pewne opóźnienie, dzięki czemu możemy być pewnym, że head
tkwi w read() przed alphabeta
produkuje pojedynczą linię wyjścia:
so$ { sleep 5; ./alphabeta; } | head -n 1
ABCDEFGHIJKLMNOPQRSTUVWXYZ
Iteration 0 done
(NB nie jest zagwarantowane, że alphabeta
będzie Iteruj tylko raz w powyższym, ale na nieobciążonym systemie, to będzie mniej więcej zawsze: head
będzie gotowy, a jego odczyt/zakończenie stanie się bardziej lub mniej natychmiastowe).
Zegarek zamiast tego, co się dzieje, gdy sztucznie opóźniać head
:
so$ ./alphabeta | { sleep 2; head -n 1; }
Iteration 0 done
...
Iteration 2415 done # <--- My system *pauses* here as pipe capacity is reached ...
Iteration 2416 done # <--- ... then it resumes as head completes its first read()
...
Iteration 2717 done # <--- pipe capacity reached again; head didn't drain the pipe
ABCDEFGHIJKLMNOPQRSTUVWXYZ
Tak na marginesie, @R .. ma rację w swoich uwagach, że SIGPIPE jest synchroniczny. W twoim przypadku pierwszy wywołany przez fflush zapis do zepsutej rury (po wyjściu head
) będzie synchronicznie generował sygnał. To jest documented behavior.
Ehm, ** 'const' **' char * s = ... ' –
Trzeba czasu, aby wypchać tytoń. – Kaz