2017-02-24 6 views
0

Hi Ich muss dieses Programm entwickeln, das 4 Kinder erstellen und nacheinander eine einfache Operation machen. Der erste wird die Summe, der zweite der Rest, der dritte die Multiplikation und der vierte die Division. Der Vater schreibt auf die Buchse die Zeichenfolge mit der zweien Zahl, die seine Kinder "berechnen" sollen, und alle Kinder sollten diese Zeichenfolge lesen, die Zahlen und die Operationen extrahieren. Offensichtlich, da es sich um zwei Pipes handelt, ist es notwendig, dass der Vater jedes Mal die Zeichenfolge schreibt, weil das Kind eingelesen wird. Ich verstehe nicht wirklich, warum ich in der zweiten Iteration eine SIGPIPE auf dem Schreiben des Vaters bekomme. Kann mir jemand erklären warum? Ich habe 3 Tage mit Debugging verbracht, aber ich habe nichts gefunden. Vielen Dank.SIGPIPE in bidirektionaler Nachrichtenübermittlung mit zwei Pipes

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

/* 
fd_0 padre escribe y hijo lee ==== padre cierra fd_0[0] y hijo cierra fd_0[1] 
fd_1 hijo escribe y padre lee === padre cierra fd_1[1] y hijo cierra fd_1[0] 
*/ 


int main (int argc, char * argv[]){ 


    char * str = malloc(100*sizeof(char));//hijo 
    char readbuffer_h[150]; 

    char * stringa = malloc(100*sizeof(char));//padre 
    char readbuffer_p[150]; 


    int a,b; 
    int x,y; 
    int n = 4; 
    int i,status,nbytes, pipe_status; 
    int pid, ppid,yo,padre; 
    int fd_0[2], fd_1[2] ; 



    pipe_status=pipe(fd_0); 
    if(pipe_status==- 1) { 
     perror("Error creando la tuberia 0\n"); 
     exit(EXIT_FAILURE); 
    } 


    pipe_status=pipe(fd_1); 
    if(pipe_status== -1) { 
     perror("Error creando la tuberia 1 \n"); 
     exit(EXIT_FAILURE); 
    } 



    for(i=0; i< n; i++){ 

     if ((pid=fork()) <0){ 
     printf("Error al emplear fork\n"); 
     exit(EXIT_FAILURE); 
     } 

/*-------------------------------------------------------------------------------------------------------------------------------------------------*/ 

     else if (pid ==0){// soy el hijo 


      yo = getpid(); 
      padre = getppid(); 
      printf("HIJO: %d, mi padre es: %d\n", yo, padre);  

      close(fd_0[1]); 
      close(fd_1[0]); 

      //TODO 


      nbytes = read(fd_0[0], readbuffer_h, sizeof(readbuffer_h)); 

      sscanf(readbuffer_h, "%d,%d", &x, &y); 


      switch(i) { 

       case 0 : 
        //TODO 
        sprintf(str, "Datos enviados a través de la tuberia por el proceso hijo: %d. Primero operando: %d, segundo operando: %d. La suma es %d", yo,x,y,(x+y)); 
        break; 

       case 1 : 
        //TODO 
        sprintf(str, "Datos enviados a través de la tuberia por el proceso hijo: %d. Primero operando: %d, segundo operando: %d. La resta es %d", yo,x,y,(x-y)); 
        break;   

       case 2 : 
        //TODO 
        sprintf(str, "Datos enviados a través de la tuberia por el proceso hijo: %d. Primero operando: %d, segundo operando: %d. El producto es %d", yo,x,y,(x*y)); 
        break; 

       case 3 : 
        //TODO 
        sprintf(str, "Datos enviados a través de la tuberia por el proceso hijo: %d. Primero operando: %d, segundo operando: %d. El cociente es %d", yo,x,y,(x/y)); 
        break; 

      } 


      write(fd_1[1], str, strlen(str)); 


      exit(EXIT_SUCCESS); 
     } 

/*-------------------------------------------------------------------------------------------------------------------------------------------------*/ 


     else{ //soy el padre 
      yo = getpid(); 
      printf("PADRE:%d\n", yo); 

      a = 3; b = 4; 

      close(fd_0[0]); 
      close(fd_1[1]); 


      sprintf(stringa,"%d,%d",a,b); 
      printf("Stringa padre : %s\n", stringa); 
       fflush(stdout); 

      write(fd_0[1],stringa,strlen(stringa)); // questa write non va a buon fine 


      wait(&status); 

      read(fd_1[0], readbuffer_p, sizeof(readbuffer_p)); 
      printf("%s\n",readbuffer_p); 
       fflush(stdout); 

     } 


    } 

close(fd_0[0]); 
close(fd_0[1]); 
close(fd_1[0]); 
close(fd_1[1]); 


return 0; 
} 
+0

Hinweis: Sie erwähnen, dass die Eltern in einen Socket schreiben, aber Sie scheinen keine Sockets zu verwenden, nur Pipes. –

+0

Ich bin mir sicher, dass er mit Englisch als Zweitsprache nur falsch spricht. – BaseZen

+0

Sorry, ich spreche immer von Rohren. (Eigentlich Englisch ist meine dritte Sprache und Spanisch die zweite ahahah) –

Antwort

1

Sie geraten in Schwierigkeiten, indem Sie versuchen, die gleichen Leitungen zu verwenden, um mit jedem Kind zu kommunizieren.

Sie erstellen zwei Pipes am Anfang des Programms. Bei der ersten Iteration der Schleife übernimmt das übergeordnete Element die Funktion, und das untergeordnete Element erbt alle geöffneten Dateideskriptoren des übergeordneten Elements. Das Kind schließt die Rohrenden, die es nicht benötigt, und das übergeordnete Element schließt die Rohrenden es nicht benötigt. Kommunikation passiert wie beabsichtigt (ich stelle mir vor) - alles gut und gut bis jetzt.

Aber jetzt betrachten Sie die zweite Iteration der Schleife. Sie verzweigen erneut und das Kind erbt erneut die geöffneten Dateideskriptoren des übergeordneten Elements. Aber jetzt wurden die Dateideskriptoren, die das Kind verwenden möchte, in der vorherigen Iteration der Schleife vom Elternteil geschlossen. Ich bin ein bisschen überrascht, dass das Kind dann eine EPIPE anstelle einer EBADF bekommt, wenn es versucht, diese Dateideskriptoren zu verwenden, aber ich bin überhaupt nicht überrascht, dass sein Leseversuch fehlschlägt.

Die sauberste Sache zu tun wäre, ein neues Paar Rohre für jedes Kind zu schaffen, anstatt zu versuchen, einen Satz Rohre wieder zu verwenden. Wenn Sie möchten, dass es nur mit dem einen Paar funktioniert, muss der übergeordnete Prozess verhindern, dass die Pipe-Enden geschlossen werden (obwohl die untergeordneten Prozesse möglicherweise ihre Kopien schließen, falls Sie dies wünschen).

Verwandte Themen