2016-08-04 147 views
1

我正在玩管道,並從here採取以下代碼;一旦我明白了,我看到一個數據塊緩存的問題,我添加了一個電話到sleep(),這是不存在的原始代碼:沖洗管道的緩衝區

#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 [這是錯的,見下面的回答]:這樣,一旦程序從其主函數返回,我確信管道的緩衝區被刷新。

但是,我仍然不明白原因:爲什麼管道的內核緩衝區會刷新到標準輸出?前者與後者有什麼關係? [編輯:這也是錯誤的,但留給上下文]

回答

2

睡眠對任何內核緩衝區沒有影響。

您在stdout上看到的輸出來自sort過程,並通過關閉grep_pipe觸發。

你的程序實際上是模仿下面的shell腳本:

ls | sort 

你打開一個管道從ls閱讀,消耗所有的輸出(來自其stdout)和該輸出發送到的該stdinsort過程。 sort無法對行進行排序,直到它包含所有行,並且只有當它關閉stdin時才知道它具有所有行,當您關閉grep_pipe時會發生這種情況。

一旦grep_pipe關閉,sort完成其工作,生成排序的行到其stdoutpclose直到關聯的進程已終止纔會返回,此時sort將完成生成其所有輸出。

+0

謝謝你澄清它。 – HeyJude