Parent Process und Child Process

Kirby.exe

Top Contributor
Also ich beschäftige mich gerade mit Processen in C und bin mal wieder dezent verwirrt xD

Soweit ich es verstanden erstelle ich mit einem fork() aufruf immer einen Kindprozess des aktuellen Prozesses. Jedoch startet dieser Prozess soweit ich verstehe immer in Programm Zeile 0 (also ganz oben in der Main Methode). Ich würde gerne ein Programm schreiben, dass alle 3 Sekunden einen Kindprozess mit fork() erstellt und dann die aktuelle PID printet. Danach soll der Kindprozess wieder geclosed werden und zurück in den Hauptprozess gesprungen werden xD Das ganze würde ich gerne 5 mal wieder holen.

Ich hatte das ganze sehr naiv mit einer Schleife probiert und mit sleep(3); jedoch wurde ca 200 prints ausgeführt xD Das liegt vermutlich daran dass ich nicht ganz verstehe wie ich einen Prozess gescheit close :)

Hier ist mal der Code, welchen ich bis jetzt haben:

C:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>

int main(){
    int process = 0;
    for(int i = 1; i <= 5; i++){
        process = fork();
        printf("Iteration: %d | PID: %d \n",i, process);
        //exit(EXIT_SUCCESS);
        sleep(3);
    }

    return 0;
}
 
K

kneitzel

Gast
Also das ist nicht korrekt. der Child Prozess geht direkt beim fork los.

Das folgende Beispiel zeigt dies recht schön:
C++:
#include <iostream>
#include <stdio.h>
#include <unistd.h>

using namespace std;


int main(int argc, char **argv)
{
    printf("Start\n");

    pid_t pid = fork();

    if (pid == 0)
    {
        printf("child process!\n");
    }
    else if (pid > 0)
    {
        printf("Parent process!\n");
    }
    else
    {
        // fork failed
        printf("fork() failed!\n");
        return 1;
    }

    printf("End (%d)\n", pid);

    return 0;
}

Ausgabe zeigt:
Start wird nur einmal ausgegeben!
Dann kommt halt einmal das parent und einmal das child ... und dann jeweils das End von Parent (Zahl > 0) und Child (Zahl = 0).


Und an meinem Beispiel erkennst Du dann auch, was Du da machen kannst. Basierend auf dem Rückgabewert kannst Du da halt den child Prozess erkennen und Prozess beenden ist dann z.B. ein Rücksprung (so es ein einfaches Programm ist und du so die main verlassen kannst) oder ein exit Aufruf tut es ebenso!

Code:
#include <iostream>
#include <stdio.h>
#include <unistd.h>

using namespace std;


int main(int argc, char **argv)
{
    printf("Start\n");

    pid_t pid = fork();

    if (pid == 0)
    {
        printf("child process!\n");
        exit(0);
    }
    else if (pid > 0)
    {
        printf("Parent process!\n");
    }
    else
    {
        // fork failed
        printf("fork() failed!\n");
        return 1;
    }

    sleep(5);
    printf("End (%d)\n", pid);

    return 0;
}

Der Code ruft dann natürlich nur noch einmal die End Ausgabe auf.
 

Kirby.exe

Top Contributor
Ok danke für deine Erklärung :) Trotzdem bin ich noch leicht verwirrt. Also nur nochmal zum Verständnis: Sobald fork() aufgerufen wird, entsteht ein Child Proccess und das Programm befindet sich dann automatisch im Child Proccess richtig? Jedoch läuft der Hauptprozess dabei ja Parallel weiter oder nicht?

Edit: Noch eine Frage zu exit(0)...Closed exit(0) den aktuellen Proccess?
 
K

kneitzel

Gast
fork erzeugt einen zweiten Prozess. Und beide Prozesse laufen parallel weiter. Und der child Prozess hat eine Kopie des Speichers.

Er hat also nicht nur eine Kopie der lokalen Variablen (Variable value, die immer erhöht wird) sondern auch des Heaps (per malloc reservierter Speicher der Klasse Test, dessen Variable immer um eins erhöht wird).

Das ist also auch wichtig. Du hast eine Kopie. Das ist also nicht ein Thread, mit dem du auf die gleichen Daten zugreifen kannst.

Wenn Du Daten austauschen willst, dann kannst Du z.B. eine pipe verwenden (siehe https://www.geeksforgeeks.org/pass-the-value-from-child-process-to-parent-process/ - das habe ich jetzt bei mir nicht eingebaut!).

C++:
#include <iostream>
#include <stdio.h>
#include <unistd.h>

using namespace std;

class Test {
public:
    int value;
};

int main(int argc, char **argv)
{
    printf("Start\n");

    Test* test = (Test *) malloc(sizeof(Test));
    test->value = 1;

    int value = 1;

    pid_t pid = fork();

    if (pid == 0)
    {
        for (int i = 0; i < 5; i++) {
            sleep(1);
            printf("child process (value = %d / %d)!\n", value, test->value);
            value++;
            test->value++;
        }
        exit(0);
    }
    else if (pid > 0)
    {
        for (int i = 0; i < 5; i++) {
            sleep(1);
            printf("parent process (value = %d / %d)!\n", value, test->value);
            value++;
            test->value++;
        }
    }
    else
    {
        // fork failed
        printf("fork() failed!\n");
        return 1;
    }

    printf("End (%d)\n", pid);

    return 0;
}
 

Neue Themen


Oben