为什么这个C程序比预期更晚生成SIGPIPE?

Bim*_*ala 16 c sigpipe

该程序SIGPIPEhead -n 1随机时间之后将其管理到" "之后生成.据我所知,因为我们在head -n 1第一行之后给"更多" ,我们会期望它生成SIGPIPE,但是在退出之前它会变成一个随机数(通常> 20和<200).知道为什么吗?

#include <stdio.h>
#include <stdlib.h>

main()
{
  int i;
  char *s = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\n";

  i = 0;
  while (1) {
    fputs(s, stdout);
    fflush(stdout);
    fprintf(stderr, "Iteration %d done\n", i);
    i++;
  }
}
Run Code Online (Sandbox Code Playgroud)

这不是家庭作业,只是我教授的笔记中我不明白的东西.

pil*_*row 8

这是调度的变幻莫测.

您的生产者 - 让我们称之为alphabeta- 能够在head能够读取和退出(因此破坏管道)之前运行一段时间.

当然,"一些时间"是可变的.

有时会alphabeta运行20次head才能读取标准输出并退出.有时200次.在我的系统上,有时300或1000或2000次.实际上,它理论上可以循环到连接生产者和消费者的管道的容量.

为了演示,让我们引入一些延迟,以便我们可以合理地确定headalphabeta生成单行输出之前卡在read()中:

so$ { sleep 5; ./alphabeta; } | head -n 1
ABCDEFGHIJKLMNOPQRSTUVWXYZ
Iteration 0 done
Run Code Online (Sandbox Code Playgroud)

(注意,不能保证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
Run Code Online (Sandbox Code Playgroud)

顺便说一句,@ R ..在他的评论中是完全正确的,即SIGPIPE是同步的.在您的情况下,第一次fflush引起的断管写入(head退出后)将同步生成信号.这是记录在案的行为.