Kurze Fragen zu Pipes und Prozesserstellung mit fork()
-
Moin,
Also hier handelt es sich um Dinge die mit fork() und pipe() zu tun haben, also müsste ich hier im richtigen Forum sein hoffe ich. Wenn nicht tuts mir leid.
Also, ich habe eine namenlose Pipe so aufgebaut:
- Im Startprozess mit dem Befehl pipe.
- Dann habe ich den Prozess mit fork() geklont
- Im Parentprozess habe ich die Lese-Verbindung geschlossen
- Im Childprozess habe ich die Schreib-Verbindung geschlossen.- Ich kann nun zwischen Parent und Child kommunizieren.
Doch: Wie merkt das Child, wenn der Parent seine Schreibeverbindung geschlossen hat?
Oder ist die einzige Möglichkeit herauszufinden, dass keine Pipe mehr besteht, in dem man den Parent Prozess beendet und im Childprozess in regelmäßigen Abständen fragt ob er mittlerweile eine neue Parent-ID hat, was bedeutet, dass sich sein "altes" Parent geschlossen hat. Hier auch nochmal die Frage: Mit wait() weiss das Parent ja wenn sich sein Child beendet. Wie kann das Child wissen wann sich sein Parent beendet? Ohne permanent abfragen zu müssen ob sich seine Parent-ID verändert hat?Und die Frage auch nochmal andersherum: Wie würde der Parent merken, dass das Child fertig aus der Pipe gelesen hat? Kann ich irgendwie abfragen wieviele Bytes gerade in der Pipe stehen? (Ich würde dann annehmen, dass das Child solange mit dem Lesen beschäftigt ist, wie in der Pipe mehr als 0 Bytes stehen).
Danke!
-
HansiDampf schrieb:
Doch: Wie merkt das Child, wenn der Parent seine Schreibeverbindung geschlossen hat?
beim nächsten Leseversuch (mit read) bekommt das Kind EOF zurück.
HansiDampf schrieb:
Wie kann das Child wissen wann sich sein Parent beendet?
Ich wüsste nicht, warum der Child Prozess so etwas wissen müsste. Ich glaube, es gibt keine Möglichkeit für so etwas.
HansiDampf schrieb:
Und die Frage auch nochmal andersherum: Wie würde der Parent merken, dass das Child fertig aus der Pipe gelesen hat? Kann ich irgendwie abfragen wieviele Bytes gerade in der Pipe stehen? (Ich würde dann annehmen, dass das Child solange mit dem Lesen beschäftigt ist, wie in der Pipe mehr als 0 Bytes stehen).
ich bin da nicht sicher (leider sagen man pages nix drüber), aber ich glaube nicht, dass man merken kann, wie viele Bytes gerade aus der Pipe gelesen wurden. Für die schreibende Seite ist das nur ein schreibender Filedeskriptor. Auch da wüsste ich nicht, weshalb man das wissen sollte. Wenn du auf Nummer sicher gehen willst, musst du vom Child ein ACK bekommen, sprich das Child sollte dir sagen "ja, hab soebene so und so erhalten".
-
guten morgen,
Danke für deine Antworten!Grüße.
-
Möchte da bitte nochmal anknüpfen...
Kannst du mir bitte sagen, wie ich abfrage, ob mein Child EOF zurückbekommt ?
Szenario: Parent liest eine Datei aus und sendet diese an das Child.
Ich hab den Lesevorgang aus der Pipe vom Child bisher so realisiert:
while ((read(fd[0], buffer, sizeof(char)))!=0) write(STDOUT_FILENO, buffer, sizeof(char)); printf("Parent hat Pipe geschlossen.");
Analog dazu den Lese und Schreibvorgang im Parent:
//filed ist der Filedeskriptor der auszulesenden Datei while ((read(filed, buffer, BUF_SIZE))!=0) { write(fd[1], buffer, BUF_SIZE); } close(fd[1]);
Das funktioniert zwar, aber nicht so wie es sollte. Ich dachte nämlich, das dass Child erst dann die 0 zurückbekommt wenn close(fd[1]) im PArent aufgerufen wurde.
Das ist aber nicht so. Die Funktion read liefert nämlich die Anzahl der gelesenen Bytes zurück. Wenn nichts zum Lesen in der Pipe steht, logischerweise 0. Aber nur weil für einen bestimmten Zeitraum nichts in der Pipe steht muss es nicht heissen, dass die Pipe geschlossen wurde!
Die Änderung der Child-Funktion in:
while ((read(fd[0], buffer, sizeof(char)))!=EOF) write(STDOUT_FILENO, buffer, sizeof(char));
Sorgt dafür, dass das letzte aus der Pipe gelesene Byte in einer Endlosschleife ausgegeben wird.
Wie muss es richtig heissen? Sprich wie kann ich verhindern, dass Schreibaussetzer des Parents vom Child fälschlicherweise als EOF intepretiert werden?
-
Die Funktion read liefert nämlich die Anzahl der gelesenen Bytes zurück. Wenn nichts zum Lesen in der Pipe steht, logischerweise 0
Nein, wenn nichts zum Lesen da ist, blockiert der Aufruf, bis etwas da ist (blocking) oder liefert -1 zurück und setzt errno auf EAGAIN (nonblocking). Das Problem liegt also irgendwo anders.
BTW, ist das Absicht dass Du im Child nur Zeichenweise liest?
-
Servus, alles klar, Danke. Dann ist es also prinzipiell der korrekte Weg danach zu schauen dass der Leser 0 empfängt. Muß nochmal schauen warunddas bei mir nicht geklappt hat...
-
Hm, ich hätte jetzt doch noch eine kurze Frage dazu, zu der ich lange gesucht aber nichts gefunden habe...
Angenommen ein Parentprozess erstellt zwei Childs.
Wie können beide Childs vom Parent lesen? Und vor allem: Was passiert wenn Child 1 aus der Pipe liest und gleichzeit Child 2 aus der Pipe liest? Sind die Daten in der Pipe nur einmal vorhanden, und es gilt mehr oder weniger zufällig, wer zu erst liest, "liest sie weg" ?
Danke.