2016-08-04 4 views
1

Ich spielte mit Rohren und nahm den folgenden Code von here; Sobald ich verstand, ich bin eine Block-Buffering Ausgabe Zeugen, habe ich eine Berufung sleep(), dass im ursprünglichen Code nicht vorhanden war:Den Puffer eines Rohrs spülen

#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 [Es ist falsch, siehe weiter unten beantworten]: Auf diese Weise, Ich stellte sicher, dass der Puffer der Pipe geleert wurde, sobald das Programm von seiner Hauptfunktion zurückkehrte.

Allerdings verstehe ich immer noch nicht den Grund: Warum würde der Kernelpuffer einer Pipe auf Standard gesetzt werden? Was hat das erstere mit letzterem zu tun? [BEARBEITEN: das ist auch falsch, aber wurde für den Kontext belassen]

Antwort

2

Der Schlaf hat keine Auswirkungen auf Kernel-Puffer.

Der Ausgang, den Sie auf stdout sehen, stammt aus dem sort Prozess und wird ausgelöst, indem der grep_pipe geschlossen wird.

Ihr Programm in der Tat ist das folgende Shell-Skript zu emulieren:

ls | sort 

Sie öffnen ein Rohr aus ls zu lesen, verbrauchen alle seine Ausgabe (von seinem stdout) und diesen Ausgang mit dem stdin der schicken sort Prozess. Das sort kann die Zeilen nicht sortieren, bis es alle Zeilen hat, und es weiß nur, dass es über alle Zeilen verfügt, wenn seine stdin geschlossen ist, was passiert, wenn Sie die grep_pipe schließen.

Sobald grep_pipe geschlossen ist, erledigt die sort ihre Arbeit und produziert die sortierten Linien zu seiner stdout. Die pclose kehrt erst zurück, wenn der zugehörige Prozess beendet wurde. Zu diesem Zeitpunkt hat der sort die Ausgabe seiner gesamten Ausgabe beendet.

+0

Vielen Dank für die Klärung. – HeyJude