20年くらい日々使っていながら、UNIX/Linuxのパイプの振る舞いをよく分かってませんでした。『易経』に「日に用いて知らず」というのはこれです。ちょっと簡単なコードで実験してみました。
リスト1 test1.c
#include <stdio.h> int main(void) { int i; for(i=0;i<5;i++){ sleep(1); printf("test1(%d)\n",i); fflush(stdout); // ←これが大事 } return 0; }
リスト2 test2.c
#include <stdio.h> int main(void) { char buff[1024]; printf("test2 starts.\n"); while(gets(buff)!=NULL){ printf("test2[%s]\n",buff); } return 0; }
実行結果
$ gcc test1.c -o test1 $ gcc test2.c -o test2 $ ./test1 | ./test2 test2 starts. ← 0秒後 test2[test1(0)] ← 1秒後 test2[test1(1)] ← 2秒後 test2[test1(2)] ← 3秒後 test2[test1(3)] ← 4秒後 test2[test1(4)] ← 5秒後 $ ← 5秒で終了
つまり
test1とtest2はパラレルに動いてて、test2のgetsが標準入力(=test1の標準出力)を同期待ちしてるんですね。