Frage von tuyjoe, 45

C - fork() Warum verhält sich meine Ausführung unterschiedlich?

Hi,

ich habe einen simplen C code. Der gestartete Prozess startet einen Kindprozess und es wird eine for Loop in beiden prozessen ausgeführt,

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

int main(){

pid_t pid;
pid = fork();

if(pid > 0){
    printf("Entering parent\n");
    for(int i = 0;i<5; i++){
                printf("%dparent\n",i); //entferne \n
                sleep(1);
        }
    printf("exit Parent\n");
}else if(pid == 0){
    printf("entering child\n");
    for(int i = 0;i<5; i++){
        printf("%dchild\n",i); //entferne \n
        sleep(1);
    }
    printf("exit Child\n");
}else{
    printf("Error on fork()");
}
    return 0;
}

Warum verhält sich die ausführung unterschiedlich (abgesehen davon das keine newLine geschrieben wird) wenn ich das \n an kommentierter stelle weglasse ?

  1. Frage:

Wie wird der sleep() Befehl in der CPU behandelt? läuft er "gleichzeitig" mit anderen Befehlen? In meinem Beispiel scheint es ja als ob beide sleep() befehle gleichzeitig runterzählen.

vielen Dank!

Hilfreichste Antwort - ausgezeichnet vom Fragesteller
von NoHumanBeing, 31

Wie wird der sleep() Befehl in der CPU behandelt? läuft er "gleichzeitig" mit anderen Befehlen?

Er wird überhaupt nicht "in der CPU" behandelt. Der Scheduler des Betriebssystems wird Deinem Prozess an dieser Stelle die "Kontrolle" über die CPU entziehen und andere Prozesse abarbeiten. Dein Prozess bekommt frühestens nach Ablauf der angegebenen Zeitspanne wieder eine Zeitscheibe.

Die Prozesse laufen unabhängig voneinander, aber jeder Prozess führt (sofern er "einfädig" ist, wie hier) stets nur einen Befehl aus. Der "sleep"-Aufruf kehrt erst dann zurück, wenn die Zeit abgelaufen ist. Die CPU wartet dabei aber nicht tatsächlich aktiv (busy waiting), sondern Dein Prozess gibt beim Aufruf von "sleep" die Kontrolle ab und "sleep" kehrt erst dann zurück, wenn er sie wieder erlangt.

Es gibt auch andere Aufrufe, die sich ähnlich verhalten. Beispielsweise kehrt ein "receive"-Aufruf auf einen Socket erst zurück, wenn der Socket auch tatsächlich Daten bereitstellt. Auch hier handelt es sich nicht um "busy waiting", sondern Dein Prozess gibt die Kontrolle ab und der Scheduler führt den Prozess erst dann wieder aus, wenn der Socket Daten bereitstellt, die vom "receive"-Aufruf zurückgegeben werden können.

Kommentar von tuyjoe ,

okay danke, kannst du mir auch sagen warum die ausführung ohne mein \n anders verläuft? hier scheint es als ob erst alle sleep() befehle abgewartet werden und dann gibt er auf einen schlag die printfs' der for loop aus.

Kommentar von NoHumanBeing ,

Ich vermute, dass das eine Eigenart der Shell ist, die Du verwendest. Diese wird die Ausgaben puffern und wenn ein Newline-Character kommt, dann wird sie den Puffer "flushen".

Du kannst das "flushen" des Puffers erzwingen, indem Du "fflush(stdout)" aufrufst. In C++ kannst Du selbiges bewirken, indem Du std::flush nach std::cout schreibst. Wenn Du std::endl (neue Zeile) nach std::cout schreibst, wird auch implizit geflushed.

Antwort
von Omnivore10, 18

Die beiden Sleeps laufen seperat, weil es auch 2 verschiedene Prozesse sind

Keine passende Antwort gefunden?

Fragen Sie die Community

Weitere Fragen mit Antworten