frage zu pipes



  • Hi,

    im folgenden code erstelle ich in der main 2 child prozesse. P1 soll daten an
    P2 senden und P2 soll diese dann in der while schleife ausgeben. Nachdem P1 die daten gesendet hat
    schließe ich die pipe mit close(pi_c1_c2[WRITE]) in der main. Wieso wird aber
    die while schleife trotzdem nicht verlassen? read sollte
    dann doch 0 zurück geben?

    Wäre super wenn mir hier wer helfen könnte.

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define READ  0
    #define WRITE 1
    
    int main(int argc, char **argv)
    {
        int pi_c1_c2[2];
        pipe(pi_c1_c2);
        int pid1,pid2;
    
        //P1  
        if((pid1 = fork()) == 0)
        {
          close(pi_c1_c2[READ]);
    
          char array[] = {'a'};
          write(pi_c1_c2[WRITE],&array[0],1);
    
          close(pi_c1_c2[WRITE]);  //Hier wird pipe geschlossen
          exit(0);
        }    
        //P2
        if((pid2 = fork()) == 0)
        {
          close(pi_c1_c2[WRITE]);
          char puffer[] = {0};
          while(read(pi_c1_c2[READ],puffer,sizeof(char)) != 0)
          {
            printf("puffer: %c\n",puffer[0]);
          }
          printf("closed\n");
          exit(0);
        }
    
        waitpid (pid1, NULL, 0);
        waitpid (pid2, NULL, 0);
    
        return 0;
    }
    


  • Dein Parent hat beide Enden der Pipe noch offen. Vor dem waitpid-Aufrufen solltest Du noch das ergänzen:

    close(pi_c1_c2[READ]);
    close(pi_c1_c2[WRITE]);
    


  • ok heisst das es reicht nicht wenn ich im child die pipe schließe (wie in zeile
    23)? Sollte nicht der schreibende prozess die pipe schließen,
    damit die verbindung abgebrochen wird. und das passiert ja in zeile 23.

    mein problem ist jetzt nämlich folgendes. P2 verlässt solange die while nicht bis
    ich die pipe in der main schließe. P1 soll aber nachdem die daten gesendet
    wurden, weitere daten an einen anderen prozess senden. das is ja aber nicht
    möglich da sich der prozess zuerst beenden muss, damit die pipe geschlossen wird
    und die while in P2 beendet wird. Also würde das so garnicht funktionieren?
    müsste ich einen neuen prozess starten, wenn ich nach dem Senden der daten in P1
    weitere daten an einen anderen prozess senden möchte?



  • worauf tntnet dich hinweist ist, dass ein pipeende erst geschlossen wird, wenn alle deskriptoren die darauf verweisen geschlossen wurden. Auch die vom Parent von P1 und P2.



  • P2 bleibt in der Schleife, bis das schreibende Ende der Pipe geschlossen wurde. Du hast es ja so programmiert, dass er das tut. Und wenn das schreibende Ende über fork dupliziert wird, dann müssen alle schreibenden Enden geschlossen werden. Dann kannst Du eben nicht mehr über diese pipe schreiben.

    Willst Du dann an einen anderen Prozess senden, dann brauchst Du entweder eine 2. Pipe oder Du musst in P2 das Abbruchkriterium anders wählen. Du könntest über die Pipe ein Protokoll definieren, woran P2 erkennt, dass er alle Daten bekommen hat. Beispielsweise sendest Du erst ein Längenfeld und dann die Daten. P2 muss das Protokoll dann eben analysieren.

    Ich sehe gerade, dass gary1195 mir zuvor gekommen ist, aber meine Antwort ist ein wenig ausführlicher.



  • Ok an die pipes im parent hab ich garnicht mehr gedacht. das is dann auch logisch.
    Jetzt funktionierts.

    Vielen dank euch 🙂


Anmelden zum Antworten