2017-05-20 2 views
0

Ich habe dieses Programm. Das Programm liest eine Anzahl von Zahlen aus der Standardeingabe, während Strg + d (EOF) gedrückt wird. Die positiven Zahlen gehen an einen Kindprozess und die negativen an einen anderen Kindprozess. Meine Frage ist: Warum sendet EOF nicht über Pipes zu den beiden Prozessen? Das ist mein Programm:STRG + D sendet nicht an die Leitung C

#include <unistd.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <errno.h> 

int p0top1[2],p0top2[2]; 

void tataWork() 
{ 
    int nr; 
    FILE *fout1, *fout2; 
    fout1 = fdopen(p0top1[1], "w"); 
    fout2 = fdopen(p0top2[1], "w"); 
    printf("Begin P0\n"); 
    while(EOF != scanf("%d", &nr)) 
    { 
     if(nr > 0) 
     { 
      fprintf(fout1,"%d\n", nr); 
      fflush(fout1); 
     } 
     else 
     { 
      fprintf(fout2,"%d\n", nr); 
      fflush(fout2); 
     } 
    } 

    close(p0top1[1]); 
    close(p0top2[1]); 
    printf("Finish P0\n"); 
} 

void p1Work() 
{ 
    close(p0top1[1]); 
    printf("Begin P1\n"); 
    int nr, i, n = 0, sum = 0, vector[1024]; 
    FILE *fin; 
    fin = fdopen(p0top1[0], "r"); 

    while(EOF != fscanf(fin, "%d", &nr)) 
    { 
     vector[n++] = nr; 
     sum += nr; 
    } 
    for(i = 0; i < n; i++) 
      printf("%d ", vector[i]); 
    close(p0top1[0]); 
    printf("Finish P1\n"); 
} 

void p2Work() 
{ 
    close(p0top2[1]); 
    printf("Begin P2\n"); 
    int nr, i, n = 0, sum = 0, vector[1024]; 
    FILE *fin; 
    fin = fdopen(p0top2[0], "r"); 

    while(EOF != fscanf(fin, "%d", &nr)) 
    { 
     vector[n++] = nr; 
     sum += nr; 
    } 
    printf("I am P2.\n"); 
    for(i = 0; i < n; i++) 
     printf("%d ", vector[i]); 
    close(p0top2[0]); 
    printf("Finish P2\n"); 
} 

void makePipe() 
{ 
    if(-1 == pipe(p0top1)) 
    { 
     perror("Error creating the pipe"); 
     exit(1); 
    } 

    if(-1 == pipe(p0top2)) 
    { 
     perror("Error creating the pipe"); 
     exit(1); 
    } 

} 

int main(void) 
{ 
    pid_t p1, p2; 

    makePipe(); 

    if(-1 == (p1=fork())) 
    { 
     perror("Error creating the child"); 
     exit(3); 
    } 

    if(p1) 
    { 
     if(-1 == (p2=fork())) 
     { 
      perror("Error creating the child"); 
      exit(4); 
     } 

     if(p2) 
     { 
      tataWork(); 
     } 
     else 
     { 
      p2Work(); 
     } 
    } 
    else 
    { 
     p1Work(); 
    } 
    return 0; 
} 

Der Ausgang ist dies:

Begin P0 
Begin P1 
Begin P2 
20 -3 4 -2 
Finish P0 

So sind die Kinder nicht beendet, weil die EOF senden nicht wahr? Sorry für mein schlechtes Englisch !!!

+0

Schauen Sie sich den Zustand Ihrer Schleife an. – Siguza

+0

Siguza scheint mir ok .... Können Sie mir sagen, was ich vermisse? – Marius

+0

Nvm, ich habe es falsch gelesen. Allerdings: Beide untergeordneten Prozesse enthalten immer noch einen Schreibdeskriptor für die Pipe des anderen Kindes. Sie schließen den Schreibdeskriptor auf ihre eigene Pipe, aber nicht auf die andere. – Siguza

Antwort

2

EOF wird von einer Rohrleitung gelesen, wenn alle fd s, die auf das Schreibende der Rohrleitung zeigen, geschlossen sind. Beide Pipes haben drei Kopien des Schreibendes (eines im Hauptprozess und eines in jedem von zwei Unterprozessen). In Ihrem Programm schließen Sie nur zwei von ihnen. In untergeordneten Prozessen schließen Sie die Pipe nicht, die vom Kind tatsächlich nicht verwendet wird (eine Kopie wurde jedoch trotzdem von der fork erstellt).

close(p0top2[1]); 

bis Anfang p1work und

close(p0top2[1]); 

bis Anfang p2Work hinzufügen und das Programm funktioniert.

+0

Es funktioniert ... Ich habe noch eine Frage, wenn Sie mir antworten wollen ... Ich möchte die Summe des ersten und zweiten Kindes an die Eltern senden ... Wie kann ich das tun? Ich habe es mit einer anderen Pipe versucht, aber es funktioniert nicht ... Ich bekomme die gleiche Ausgabe ... Ich denke, es ist, weil die neue Pipe, aber wenn ich es schließe, wie kann ich es zurück zu den Eltern schicken? – Marius

+0

@Marius Um Ergebnisse vom Kind zum Hauptprozess zurückzusenden, würde ich ein weiteres Paar von Pipes im Hauptprogramm vor 'fork's erstellen. Sie lesen die Ergebnisse aus dem Lesen endet im Hauptprozess und schreiben an die Schreibenden in Childs. – Marian

Verwandte Themen