anfänger; mit fork() child-prozess erzeugen
-
CStoll schrieb:
und aktuell arbeiten beide Prozesse die selben Anweisungen ab - eventuell solltest du in der if(ich bin child)-Abfrage ein return ans Ende setzen, sonst kommt der Kind-Prozess nach dem Ende seiner "eigenen" Anweisungen zurück auf den Block des Hauptprogramms.
Hi
nun, ihrgendwie versteh ich das noch nicht so ganz.
Wie kann ich dem Parentprozess sagen, dass er den if ( child >= 0 ) { * } nicht abarbeiten soll und direkt zu sleep(5); springt?Desweiteren werd ich heute Abend eben mal die if ( child >= 0 ) { * } mit einem return 0; erweitern, also if ( child >= 0 ) { *; return 0; }. (Hier wird ja der Parent Prozess beendet, wenn er auch die Anweisungen in der if Schleife abarbeitet..) Kann ich diese beiden Prozesse nicht ganz voneinander trennen? Oder ist vielleicht fork() die falsche Funktion?
Vielen Dank für eure Hilfe.
Gruss
-
Ganz einfach, die Bedingung in if() ist falsch:
if(child==0) { Anweisungen für Kind; return 0; } else if(child==-1) { cout<<"Fehler"<<errno; } else //child > 0 { Anweisungen für Vater; }
man: fork liefert entweder 0 (Kind), den positiven PID des Kinds (Vater) oder -1 (bei Fehler) - also mußt du die Verzweigung auch daran ausrichten.
-
Ich denke es fällt den meisten Neulingen schwer, zu begreifen, dass eine Funktion (fork), die man einmal aufruft, zweimal zurückkehrt
In dem Moment, wo du fork() aufgerufen hast, wird der folgende Code zweimal parallel durchlaufen! In welcher der beiden Prozesse Du bist sagt Dir der Returncode von fork... der eine erhält 0 zurück, der andere > 0.
Dass du mit if (code >= 0) beide erwischt dürfte jetzt einleuchtend sein
-
Wenn du mit fork() einen neuen Prozess startest und dein Programm mit printf() oder fprintf() arbeitet (bzw. "cout" bei C++), musst du bedenken, dass der mit fork() erzeugte neue Prozess eine Kopie des alten darstellt inkl. aller Pufferinhalte! Auch dadurch kann es u. U. zu einer Doppelung der Ausgabezeilen kommen.
Abhilfe: Vor dem fork()-Aufruf die Puffer mit fflush() leeren - z. B. fflush(stdout).Eine einsteigergerechte Beschreibung des Umgangs mit fork() und Interprozesskommunikation findest du auch in meinem Buch "C und Linux".
Martin
-
-
Martin G schrieb:
Eine einsteigergerechte Beschreibung des Umgangs mit fork() und Interprozesskommunikation findest du auch in meinem Buch "C und Linux".
Martin
Denkst du (naja du hast es ja geschrieben, also "weisst du"
) ob das Buch auch gut für C++ geeignet ist? Es ist zwar vieles gleich, aber gibt ja trozdem ein paar Unterschiede. Z.B. Bibliotheken. Wenn ich da im Buch nur wirklich C spezifisches finde nützt es mir ja nicht all zu viel..?
-
perati- schrieb:
Denkst du (naja du hast es ja geschrieben, also "weisst du"
) ob das Buch auch gut für C++ geeignet ist? Es ist zwar vieles gleich, aber gibt ja trozdem ein paar Unterschiede. Z.B. Bibliotheken. Wenn ich da im Buch nur wirklich C spezifisches finde nützt es mir ja nicht all zu viel..?
Leider kann ich diese Frage nicht umfassend beantworten - dazu bin in C++ nicht fit genug. Aber vielleicht hilft dir dieser Beitrag weiter.
-
Hi Forum
Ich habe ja so ein kleines Testprogramm geschrieben..
Nun, auf dem Rechner auf welchem ich es schrieb funktionierte es, dass der parentprozess auf den childprozess wartete und zwar mit waitpid(pidchild, 0, 0)
Nun auf diesem Rechner funktioniert es nicht mehr, der Parentprozess wird beendet sobald er seine Aufgabe erledigt hat, also sobald cout<<"3. parent nach 5sec\n"; ausgefürt wurde.Hier mal den Code:
#include <iostream> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> using std::cout; int main() { int child; int pidchild; cout << "1. parent prozess\n"; child = fork(); if(child == 0) { cout << " 2. child gestartet\n"; pidchild=getpid(); cout << " childpid= " << pidchild <<"\n"; sleep(10); cout << " 4. child nach 10sec\n"; return 0; } else if(child == -1) { cout <<"Fehler: " <<errno<<"\n"; } else // child > 0 { sleep(5); cout<<"3. parent nach 5sec\n"; waitpid(pidchild, 0, 0); } }
Erlich gesagt finde ich das sehr seltsam? Weiss echt jemand an was das liegen könnte?
waitpid() ist so schon richtig aufgebaut? Ohne zusätzliche Optionen und den Status will ich auch nicht abrufen..Vielen dank für eure Hilfe
Gruss perati
PS: Martin G, ok thx für den Link
ich glaub ich befass mich mit C++ und C..
gruss
-
äh, fork liefert dir im parent doch die child pid zurück (ist übrigend pid_t und nicht int!). Daher kannst du ja einfach waitpid für child aufrufen.
Aber was ganz wichtig ist, dass du in Prozess A nicht die Variablen für Prozess B ändern kannst (ausgenommen shared memory, aber dass ist erst einmal unwichtig).
childpid ist also im parent prozess undefiniert, daher ist auch der aufruf für waitpid mit childpid undefiniert.
Lies dich am besten mal in das Thema ein.
-
kingruedi schrieb:
äh, fork liefert dir im parent doch die child pid zurück (ist übrigend pid_t und nicht int!). Daher kannst du ja einfach waitpid für child aufrufen.
also einfach waitpid(child, 0, 0); naja.. -> 2. letze Zeile
also sry wenn ich ein bisschen nerve, aber im Parentprozess ist "child" einfach die pid von childporzess und im childprozess ist "child" einfach 0 ? hab ichs jetzt?kingruedi schrieb:
Aber was ganz wichtig ist, dass du in Prozess A nicht die Variablen für Prozess B ändern kannst (ausgenommen shared memory, aber dass ist erst einmal unwichtig).
Au.. was für ein riesen Überlegungsfehler von mir
Ich dachte ihrgendwie, wenn die Var ja vorher deklariert wurde, dann passt das schon..
kingruedi schrieb:
childpid ist also im parent prozess undefiniert, daher ist auch der aufruf für waitpid mit childpid undefiniert.
Ja, eigentlich logisch.. ich frag mich jetzt wieso das beim anderen Rechner ging?? Das haben sogar 4 Augen gesehen. Naja, am Montag kann ichs ja nochmals anschauen
kingruedi schrieb:
Lies dich am besten mal in das Thema ein.
Hab ich wohl nötig
Gruss und Danke ! perati
-
perati- schrieb:
also sry wenn ich ein bisschen nerve, aber im Parentprozess ist "child" einfach die pid von childporzess und im childprozess ist "child" einfach 0 ? hab ichs jetzt?
Heureka - er hat's gefunden
kingruedi schrieb:
Aber was ganz wichtig ist, dass du in Prozess A nicht die Variablen für Prozess B ändern kannst (ausgenommen shared memory, aber dass ist erst einmal unwichtig).
Au.. was für ein riesen Überlegungsfehler von mir
Ich dachte ihrgendwie, wenn die Var ja vorher deklariert wurde, dann passt das schon..
Auch wenn sie vorher deklariert ist, hat nach dem fork() jeder Prozess eine eigene Kopie der Variablen.