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