2016-08-04 5 views
1

私はパイプで遊んでいましたが、次のコードをhereから取り出しました。このようパイプのバッファをフラッシュする

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

int main() 
{ 
    FILE *ps_pipe; 
    FILE *grep_pipe; 

    int bytes_read; 
    int nbytes = 100; 
    char *my_string; 

    char buffer[100]; 

    /* Open our two pipes */ 
    ps_pipe = popen ("ls", "r"); 
    grep_pipe = popen ("sort", "w"); 

    /* Check that pipes are non-null, therefore open */ 
    if ((!ps_pipe) || (!grep_pipe)) 
    { 
     fprintf (stderr, 
       "One or both pipes failed.\n"); 
     return EXIT_FAILURE; 
    } 

    bytes_read = 0; 
    while (fgets(buffer, sizeof(buffer), ps_pipe)) 
    { 
     fprintf(grep_pipe, "%s", buffer); 
     bytes_read += strlen(buffer); 
    } 

    printf("Total bytes read = %d\n", bytes_read); 
    sleep(2); 

    /* Close ps_pipe, checking for errors */ 
    if (pclose(ps_pipe) != 0) 
    { 
     fprintf(stderr, "Could not run 'ps', or other error.\n"); 
    } 

    /* Close grep_pipe, cehcking for errors */ 
    if (pclose(grep_pipe) != 0) 
    { 
     fprintf(stderr, "Could not run 'grep', or other error.\n"); 
    } /* Exit! */ 

    return 0; 
} 

EDIT [それは間違っている、以下の答えを参照]:私はブロックバッファリングの問題を目の当たりにしています理解したら、私は元のコードに存在していなかったことsleep()に呼び出しを追加しましたプログラムのmain関数から返されたパイプのバッファがフラッシュされたことを確認しました。

しかし、私はまだ理由を理解していません:なぜパイプのカーネルバッファをstdoutにフラッシュするのですか?前者は後者と何をしなければならないのですか? [編集:これも間違っていますが、コンテキストのために残りました]

答えて

2

スリープはカーネルバッファに影響しません。

stdoutに表示される出力はsortプロセスからのもので、grep_pipeを閉じることによってトリガーされます。

あなたのプログラムは、次のシェルスクリプトをエミュレートする効果である:

ls | sort 

あなたは、lsから読み取る(そのstdoutから)その出力のすべてを消費してのstdinに、この出力を送信するためにパイプを開きますsortプロセス。 sortは、すべての行を含むまで行を並べ替えることができません。grep_pipeを閉じると、stdinが閉じられたときにすべての行があることがわかります。

grep_pipeが閉じられると、sortが処理され、ソートされた行がstdoutになります。 pcloseは、関連付けられたプロセスが終了するまで戻りません。その時点で、sortはすべての出力を終了します。

+0

ありがとうございます。 – HeyJude

関連する問題