这是日程安排的变幻莫测。
你的生产者——我们称之为它alphabeta
——能够运行一段时间,然后head
才能读取和退出(从而破坏管道)。
当然,“一些时间”是可变的。
有时alphabeta
运行 20 次head
才能读取标准输入并退出。有时200次。在我的系统上,有时 300 或 1000 或 2000 次。事实上,理论上它可以循环到连接生产者和消费者的管道的容量。
为了演示,让我们引入一些延迟,以便我们可以合理地确定在产生单行输出head
之前卡在 read()中:alphabeta
so$ { sleep 5; ./alphabeta; } | head -n 1
ABCDEFGHIJKLMNOPQRSTUVWXYZ
Iteration 0 done
(注意,不能保证alphabeta
只会在上面迭代一次。但是,在未加载的系统上,或多或少总是会出现这种情况: head
准备就绪,并且它的读取/退出将或多或 -立即减少。)
请注意当我们人为地延迟时会发生什么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
顺便说一句,@R.. 在他的 SIGPIPE 是同步的评论中是完全正确的。在您的情况下,第一次 fflush 引起的对损坏管道的写入(head
退出后)将同步生成信号。这是记录在案的行为。