/* 15May24: Erstes Beispiel für fork+waitpid. */ #include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <sys/weit.h> /**********************************************/ /* Ein Prozess ist ein Programm in Ausführung */ /**********************************************/ int main(int argc, char *argv[]) { pid_t pid; /* Mit fork(2) wird ein neuer Prozess erstellt. Der neue Prozess * führt weiter den gleichen Prozess aus, und hat eine Kopie * aller Daten (die beiden Prozess haben jedoch getrennte * Speicherräume: Wenn sich in einem Prozess was ändert, wird das * nicht von dem Klon übernommen und gespiegelt). */ pid = fork(); /* Prozesse auf einem System sind eine endliche Ressource * (brauchen ja Speicher): Sie können ausgehen und dann wird * fork() fehlschlagen. Hier muss man abwägen ob es wirklich ein * fataler Vorfall ist, bevor man dann das Programm beendet. */ if (pid == -1) { perror("fork"); return EXIT_FAILURE; } /* Der unterschied zwischen dem neuen und dem alten Prozess ist * zunächst nur der Rückgabewert. Im neu erzeugtem "Kind", gibt * fork() den Wert 0 zurück, und im altem "Eltern"-Prozess die * PID (Process IDentification) des Kinds. Anhand kann das * verhalten variieren. */ if (pid == 0) { puts("I am the child"); return 55; /* beliebiger Wert */ } else { puts("I am the parent"); /* Eltern-Prozesse können auf die Kinder warten: Mit * waitpid(2) gibt man eine spezifische PID an und die * Ausführung wird so lange blockiert, bis der * referenzierte Prozess sich beendet. * * Die Funktion nimmt darüber hinaus noch zwei Argumente: * * - Ein int-Pointer, hinter den Information zu dem * terminiertem Prozess gespeichert wird. * * - Eine Option in Form eines Bit-Felds. D.h. wenn man die * default Optionen übernehmen will, setzt man 0, und * ansonsten veroder't man zusätzliche Optionen bit-weise: * * 0 | WNOHANG ≡ WNOHANG * * (diese Option blockiert nicht, sondern lässt waitpid * nur prüfen ob der Prozess sich beendend hat). */ int stat_loc; waitpid(pid, &stat_loc, 0); /* FEHLERBEHANLUNG FEHLT! */ /* In der wait(3) manpage sind Makros definiert, womit man * aus `stat_loc' Informationen herauslesen kann. * Bspw. prüfen wir hier erst ob das Programm sich normal * beendet hat (anstatt das es abgeschossen wurde, bspw * wegen einem Segmentation Fault), in welchem Fall wir den * Exit Status auslesen können. Haben wir die erste * Zusicherung nicht, ist es nicht gültig den Status-Code zu * lesen. */ if (WIFEXITED(stat_loc)) { printf("Child exited with %d\n", WEXITSTATUS(stat_loc)); } else { puts("Child did not exit with a status code"); } return EXIT_SUCCESS; } }