[C/C++] fork and join - wie funzt das genau?

Dieses Thema im Forum "Programmierung & Entwicklung" wurde erstellt von Pac_-_man, 3. November 2009 .

Schlagworte:
Status des Themas:
Es sind keine weiteren Antworten möglich.
  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies. Weitere Informationen
  1. #1 3. November 2009
    fork and join - wie funzt das genau?

    Hallo!

    Bin die ganze Zeit am googlen, aber finde irgendwie nichts brauchbares... Es geht um parallele Prozesse und wie das genau mit fork und join funktioniert. Bisher habe ich rausgefunden, dass man zum Beispiel mit dem Befehl "fork" einen Prozess (oder Thread?) kopieren kann und somit 2 Prozesse des gleichen Programms (quasi)parallel laufen lassen kann.

    Ich frage mich nur: was soll das ganze? wie funktioniert es genau? wann macht es sinn sowas zu machen?

    Ich steh total aufm Schlauch. Wäre echt Klasse, wenn mir das jemand vlt ein bisschen näher bringen kann oder eine Seite kennt wo das mal vernünftig for dummys erklärt ist. Glaub nämlich irgendwie nicht dass da soviel hintersteckt..

    Danke schonmal!
    mfg
     

  2. Anzeige
    Heute: Deals & Sale mit stark reduzierten Angeboten finden.
  3. #2 3. November 2009
    AW: fork and join - wie funzt das genau?

    ich kann dir das anhand der php-implementierung ein wenig erklären.

    via fork kannst du das aktuell laufende programm kopieren, also alle variablen etc werden da übernommen und in nem neuen prozess (mit neuer PID) ausgeführt.

    viele programme nutzen diese methode um sich in den hintergrund zu "forken".

    ein fork (dt. gabel) blockiert nämlich die konsole ned. nur das programm das du gestartet hast is auf der konsole, alle forks des programms laufen im hintergrund.

    mit der implementierung kannst du dann signale an deine forks senden und wenn du die forks nicht mehr brauchst musst du sie wieder "einsammeln" - also beenden.

    is meiner meinung nach ein sehr schwer zu erklärendes thema.

    wann macht es sinn sowas zu machen?
    im grunde dann, wenn du unabhängig sachen ararbeiten willst.
    dann kannst du nämlich lauter kleine klone losschicken und jeder klon macht nen kleinen teil und am ende bist du x-mal schneller fertig als wenn dus in einem programm nach der reihe gemacht hättest.

    das problem dabei is halt, das du die teile wirklich wieder einsammeln musst, sonst hast du lauter kleine (sog.) zombies.

    auch bei server und anderen diensten die immer laufen, aber nix blockieren sollen (zb. apache, mysql).
    diese teile nennt man dann daemons, weil sie im hintergrund laufen und keiner auf anhieb sieht das die teile existieren (konsole is leer und bereit -> aber das ding läuft).
     
  4. #3 3. November 2009
    AW: fork and join - wie funzt das genau?

    ok, also wie es funktioniert habe ich verstanden denke ich und auch wie ich mir das im Speicher vorstellen muss. aber wodurch genau wird denn dieser starke Geschwindigkeitsvorteil verursacht?

    Also es laufen jetzt verschiedene Prozesse auf meinem System. jeder wird abwechselnd vom Prozessor bearbeitet (also quasiparallel). Nun klone ich meinen Prozess, lass die Kinderprozesse verschiedene Aufgabe erledigen und schließe sie am Ende wieder alle. Liegt der Vorteil jetzt nur darin, dass wenn es mehrere Prozesse vom gleichen Programm gibt (die halt verschiedene Dinge bearbeiten) der Prozessor dem gesamten Programm mehr "Aufmerksamkeit" widmet? (also beim quasiparallelem bearbeiten der Prozesse)

    Kannst du vlt auch ein kleines Pseudocodebsp. schreiben, wie man fork korrekt verwendet? Das wäre klasse! schonmal danke, deine erklärung habe ich verstanden!
     
  5. #4 3. November 2009
    AW: fork and join - wie funzt das genau?

    also ich weiss zwar net ganz genau ob das das selbe ist wie threads, aber es hört sich so an
    wenn dem so ist dann ergibt sich der zeitvorteil einfach daraus, dass du eingaben machen kannst, während zB ein anderer prozess ausgeführt wird.
    die BERECHNUNGSZEIT bleibt gleich, aber die Zeit in der das Programm ausgeführt wird sinkt, weil eben die Zeit in der das Programm wartet, weil du zB was eingeben musst oder zB auf eine Reaktion eines andren Programms/Server/Client gewartet wird "geringer" wird.

    Das macht sich eben bei komplzierteren Sachen erst bemerkbar.
    Oder zB wenn du mit Server/Client arbeitest.
    Sagen wir du willst eine Verbindung zu 5 Server aufbauen.
    In der Zeit wo das Programm dann nichts berechnet, kann ein anderer Thread eben die nächste Verbindung öffnen. Anstatt das erst die erste, danach die zweite, danach die dritte usw. geöffnet wird.
     
  6. #5 4. November 2009
    AW: fork and join - wie funzt das genau?

    @Anqueetus: es ist im prinzip genau das gleiche wie multithreading. mein prof hat mir das auch nochmal so erklärt. also das man wirklich nur dadurch zeit rausholt, dass man völlig voneinander unabhängige dinge parallel abarbeiten kann, wenn ein thread warten muss.ich frage mich nur gerade wie man fork() nun konkret anwedet. und vor allem: wie kann ich die ergebnisse von verschiedenen geforkten threads ieder zusammenführen?

    wäre echt gut, wenn jemand ein kleines pseudocodebspl. posten könnte!

    mfg
     
  7. #6 5. November 2009
    AW: fork and join - wie funzt das genau?

    Hallo!

    Ich kann dir als Einstieg mal mein fork-Halbwissen preisgeben :)

    man page fork section 2

    Code:
    pid_t fork(void);
    Die Grundidee: Mit fork () kann man in einem linear geschriebenem Programm Code parallel ausfuehren!

    Das ganze laeuft so ab:
    Code:
    pid_t pid = fork ();
    
    /* fork () hat aus irgendeinem Grund nicht geklappt - unwahrscheinlich */
    if (pid == -1)
     perror ("fork () failed");
    
    if (pid == 0)
    {
     /* Hier sind wir im child-Prozess (sozusagen im Thread) */
     printf ("Hallo, ich bin der child-Prozess!\n");
     printf ("Ich beende mich jetzt mit dem Statuscode %u...\n", CHILD_RETURN_CODE);
     
     exit (CHILD_RETURN_CODE);
    }
    else
    {
     /* Hier sind wir im parent-Prozess (sozusagen das Hauptprogramm) */
     printf ("Ich bin das Hauptprogramm!");
     
     /* Hier kanns im Hauptprogramm weitergehen */
     mach_irgendwas_anderes ();
    }
    Hier ein ausfuehrlicheres Beispiel auf Englisch.

    Das ganze ist noch etwas 'komplizierter', weil der child-Prozess als 'Zombie' uebrig bleibt (Zombie bedeutet, dass er nicht vollstaendig terminiert ist). Da braucht man dann einen SIGNAL-Handler, der das uebernimmt (MAN-page lesen).

    Hoffe das klaert die Sache ein bisschen auf.

    Uebrigens halte ich fork () fuer keine gute Idee. Es gibt bessere Thread-Implementierungen. Um mal schnell einen Thread in ein Programm einzubauen, ists OK, aber fuer groessere Projekte zu fehleranfaellig (im Performance Sinn). Du kannst ja mal schauen, wie lang dein System ueberlebt:
    Code:
    while (fork () != -1) { fork ();}
    :p

    Gut... der Sinn hinter dem ganzen: Man kann damit z.B. einen Server bauen, der dauernd auf Clients wartet. Sobald sich ein Client verbindet, wird ge-fork()-ed, der Child-Prozess ist wie ein eigenstaendiges Programm, das mit einem einzigen Client arbeitet, und der Hauptprozess wartet weiter auf Clients. Ohne fork () koennte man sich naemlich nur um 1 Client gleichzeitig kuemmern (ausser man nimmt z.B. select () als Hilfe). Ist halt eine andere Art, eine multi-thread Application zu basteln.

    Ein andere Idee, wie bereits von Murdoc angedeutet: Du kannst z.B. zwei unabhaengige Rechnungen durchfuehren lassen, die eine im Child-Prozess, die andere im Parent-Prozess, und die spaeter wieder zusammenfuehren (Beispiel: (10 + 5) * (5 - 3)). Danach wartet der Parent-Prozess auf die Terminierung des Child-Prozesses (mit wait (); falls z.B. die Berechnung in dem Thread noch andauert) und bekommt das Ergebnis z.B. mit WEXITSTATUS(status). Das Hauptprogramm kann jetzt weitermachen und wurde schneller ausgefuehrt (auf einem Dual-Core Prozessor auf jeden Fall). Damit wurde (10 + 5) gleichzeitig mit (5 - 3) ausgerechnet (ein Schritt), und das Hauptprogramm kann nun das Ergebnis ausrechnen (2. Schritt). Ohne fork () waerens insgesamt 3 Schritte gewesen (1.: (10 + 5); 2.: (5 - 3); 3.: 15 * 2).

    Mfg,

    Kolazomai
     
  8. #7 5. November 2009
    AW: fork and join - wie funzt das genau?

    Das "Problem" an fork() ist halt, dass die gesamte Prozessstruktur im RAM kopiert wird, was u.U. sehr ressourcenfressend ist. Du hast dann ja quasi 2 Prozesse im Speicher.
    Threads hingegen laufen auch parallel ab, sind aber leichtgewichtiger als Prozesse.

    Aber es kommt natürlich auf den Fall an, was du genau erreichen willst.
     
  9. #8 5. November 2009
    AW: fork and join - wie funzt das genau?

    So habe mir Antworten nciht durchgelesen.
    Doch fork ist/war nur unter Linux verwendbar.
    Es erzeugt einen "childprozess" der eig. alles von dem Hauptprozess erbt, also wie du gesagt hast eine art Thread.

    Belehrt mich wenn ich falsch liege meine C++ Zeit liegt schon hinter mir ^^
     
  10. #9 11. November 2009
    AW: fork and join - wie funzt das genau?

    sorry das ich so lange nicht genantwortet habe....

    vielen dank für die vielen beiträge! vorallem an Kolazomai für das beispiel. hat mir sehr geholfen! ist ja eigentlich garnicht so wild. ich hatte mich nur über nsere Hausaufgaben gewundert, da wir dort die Mandelbrotmenge berechnen und das mit fork/join parallelisieren sollten. Und da hatte cih mich nun gefragt (da ja bei der berechnung nirgendwo irgendwie auf eingaben oder so gewartet wird) wie man das mit fork/join hätte beschleunigen können. aber es soll wohl einfach nur parallelisiert werden, so dass es auf multicore prozessoren schneller läuft.

    eigentlich ne kleinigkeit, aber es hat mir keine ruhe gelassen^^ also nochmals danke an alle! ihr wart mir mal wieder eine große hilfe!

    mfg
     

  11. Videos zum Thema
Die Seite wird geladen...