Vater- und Kindprozesse



  • fork hast du auch falsch benutzt, du kannst nicht fork einfach so 2 Mal hintereinander ausführen, weil du nicht 2 sondern 3, weil der erste Kindprozess ebenfalls pid_2 = fork(); ausführt.



  • supertux schrieb:

    fork hast du auch falsch benutzt, du kannst nicht fork einfach so 2 Mal hintereinander ausführen, weil du nicht 2 sondern 3, weil der erste Kindprozess ebenfalls pid_2 = fork(); ausführt.

    Diese Aussage verstehe ich nicht ganz. Es ist doch so, dass die Anweisungen

    pid_1 = fork();
    pid_2 = fork();
    

    zwei Kindsprozesse erzeugen, richtig?

    Wie muss dies denn stattdessen lauten?



  • Pinkepank schrieb:

    Diese Aussage verstehe ich nicht ganz. Es ist doch so, dass die Anweisungen

    pid_1 = fork();
    pid_2 = fork();
    

    zwei Kindsprozesse erzeugen, richtig?

    Nein, der erste fork erzeugt einen Kindprozess. Der Vaterprozess ist aber auch noch da, so dass nun beide Prozesse den zweiten fork durchlaufen. Dieser erzeugt im Vaterprozess einen neuen Kindprozess, und im ersten Kindprozess auch. So hast Du anschließend vier Prozesse.

    Die Lösung wäre, anhand von pid_1 zuerst zu entscheiden ob Du im Vater- oder Kindprozess bist, und nur im Vaterprozess das zweite mal zu forken.



  • Ich hätte auch eine kleine Frage: Wie finde ich im Vaterprozess heraus, ob ein Kindprozess noch läuft?



  • Alter Grieche schrieb:

    Ich hätte auch eine kleine Frage: Wie finde ich im Vaterprozess heraus, ob ein Kindprozess noch läuft?

    man: waitpid(2)



  • wait kenne ich. Ich möchte aber nur herausfinden ob der Kindprozess noch läuft. Der Vaterprozess soll nämlich etwas machen, solange der Kindprozess noch läuft und nicht bloß warten:

    while(child_is_still_alive(pid))
    {
      do_something_usefull();
      do_more_usefull_things();
    }
    


  • So, habe den Quelltext ein wenig umgebaut:

    #include <stdio.h>
    #include <unistd.h>
    #include <time.h>
    #include <sys/types.h>
    #include <stdlib.h>
    
    int main()
    {
       int pid_1;
       int pid_2; 
       int i = 5;
       int n = 98;
    
       time_t timer;
    
       pid_1 = fork();
    
       /*Sohnprozess*/
    
       if(pid_1 == 0) {
    
          sleep(15);
    
       /*Vaterprozess*/
    
       } else if (pid_1 > 0) {
    
       pid_2 = fork();
    
       if(pid_2 == 0) {
    
       	  while(1) {
       	     n+i;
       	  }
       }
    
       printf("PID Vater : %d\n", (int) getpid());
       printf("PID Sohn 1: %d\n", pid_1);
       printf("PID Sohn 2: %d\n", pid_2);
    
       sleep(1);
       sleep(1);
       sleep(1);
       sleep(1);
       sleep(1);
       sleep(1);
    
       printf("Zeit: %s\n", asctime(localtime(&timer)));
    
       }
    return 0;
    }
    


  • Ist es beabsichtigt, dass der erste Kindprozess nach seiner 15 sekündigen Wartezeit auch alles ab Zeile 36 durchläuft? Normalerweise setzt man eine return 0; ans Ende jedes Kind-Zweiges:

    #include <stdio.h>
    #include <unistd.h>
    #include <time.h>
    #include <sys/types.h>
    #include <stdlib.h>
    
    int main()
    {
       int pid_1;
       int pid_2; 
       int i = 5;
       int n = 98;
    
       time_t timer;
    
       pid_1 = fork();
    
       /*Sohnprozess*/
    
       if(pid_1 == 0) {
    
          sleep(15);
    
          return 0;
    
       /*Vaterprozess*/
    
       } else if (pid_1 > 0) {
    
       pid_2 = fork();
    
       /*Sohnprozess*/
    
       if(pid_2 == 0) {
    
       	  while(1) {
       	     n+i;
       	  }
       return 0;
       }
    
       /*Vaterprozess*/
    
       printf("PID Vater : %d\n", (int) getpid());
       printf("PID Sohn 1: %d\n", pid_1);
       printf("PID Sohn 2: %d\n", pid_2);
    
       sleep(1);
       sleep(1);
       sleep(1);
       sleep(1);
       sleep(1);
       sleep(1);
    
       printf("Zeit: %s\n", asctime(localtime(&timer)));
    
       }
    return 0;
    }
    


  • Mehr oder weniger ;). Ich habe die Aufgabenstellung aus einem Buch über Betriebssysteme. Dort wird aber über den von dir aufgeführten Sachverhalt kein Wort verloren.

    Eine weitere Frage:

    #include <stdio.h>
    #include <unistd.h>
    #include <time.h>
    #include <sys/types.h>
    #include <stdlib.h>
    
    int main()
    {
       int pid_1;
       int pid_2; 
       int i = 5;
       int n = 98;
    
       time_t timer;
    
       pid_1 = fork();
    
       /*Sohnprozess*/
    
       if(pid_1 == 0) {
    
          sleep(15);
          exit(0);   
       /*Vaterprozess*/
    
       } else if (pid_1 > 0) {
    
       pid_2 = fork();
    
       if(pid_2 == 0) {
    
       	  while(1) {
       	     n+i;
       	  }
          exit(0);   
       }
    
       printf("PID Vater : %d\n", (int) getpid());
       printf("PID Sohn 1: %d\n", pid_1);
       printf("PID Sohn 2: %d\n", pid_2);
    
       sleep(1);
       sleep(1);
       sleep(1);
       sleep(1);
       sleep(1);
       sleep(1);
    
       printf("Zeit: %s\n", asctime(localtime(&timer)));
    
       system("ps -H");
    
       exit(0);
    
       }
    return 0;
    }
    

    Ich möchte gerne die erzeugten Prozesse auch wieder beendigen. Dies funktioniert, wie ich nachlesen konnte mit der exit()-Funktion. Den ersten Sohn sowie den Vater kann ich problemlos beendigen, den zweiten Sohn jedoch nicht. Woran kann dies liegen?



  • Weil er in einer Endlosschleife festsitzt.
    BTW: Innerhalb der main() -Funktion ist return 0; und exit(0); das selbe.



  • Alter Grieche schrieb:

    wait kenne ich. Ich möchte aber nur herausfinden ob der Kindprozess noch läuft. Der Vaterprozess soll nämlich etwas machen, solange der Kindprozess noch läuft und nicht bloß warten:

    while(child_is_still_alive(pid))
    {
      do_something_usefull();
      do_more_usefull_things();
    }
    

    man: waitpid(2) <-- siehe manual. (beachte die options) 🙄



  • Gibt es denn trotz der Endlossschleife eine Möglichkeit den Prozess zu beenden (wenn möglich vom Vaterprozess aus)?





  • Auf kill() war ich auch schon gekommen, allerdings funktionierte dies nicht so richtig.

    #include <stdio.h>
    #include <unistd.h>
    #include <time.h>
    #include <sys/types.h>
    #include <stdlib.h>
    #include <signal.h>
    
    int main()
    {
       pid_t pid_1;
       pid_t pid_2; 
       int i = 5;
       int n = 98;
    
       time_t timer;
    
       pid_1 = fork();
    
       /*Sohnprozess*/
    
       if(pid_1 == 0) {
    
          sleep(15);      
          exit(0);   
    
       /*Vaterprozess*/
    
       } else if (pid_1 > 0) {
    
       pid_2 = fork();
    
       if(pid_2 == 0) {
    
       	  while(1) {
       	     n+i;
       	  }
          kill(pid_2, 0);
       }
    
       printf("PID Vater : %d\n", (int) getppid());
       printf("PID Sohn 1: %d\n", pid_1);
       printf("PID Sohn 2: %d\n", pid_2);
    
       printf("Zeit: %s\n", asctime(localtime(&timer)));
    
       system("ps -H");
       exit(0);
    
       }
    return 0;
    }
    

    Habe den kill-Aufruf testweise bei dem ersten Kind angewendet, wo er funktionierte.



  • denk doch mal nach. Wie sollte das bitte funktionieren? 🙄

    Und lies dir auch mal die Manpage durch 🙄



  • rüdiger schrieb:

    denk doch mal nach. Wie sollte das bitte funktionieren? 🙄

    Und lies dir auch mal die Manpage durch 🙄

    Nun, da du ja schon so freundlich darauf hinweist, wird es wohl am zweiten Parameter liegen. Allerdings sagen mir die unter "sigaction" befindlichen Parameter nicht wirklich viel (Anfänger am Werk).



  • Pinkepank schrieb:

    rüdiger schrieb:

    denk doch mal nach. Wie sollte das bitte funktionieren? 🙄

    Und lies dir auch mal die Manpage durch 🙄

    Nun, da du ja schon so freundlich darauf hinweist, wird es wohl am zweiten Parameter liegen. Allerdings sagen mir die unter "sigaction" befindlichen Parameter nicht wirklich viel (Anfänger am Werk).

    Nein. Also das würde das Problem sein, wenn kill überhaupt aufgerufen wird. Aber du solltest erst einmal drüber nachdenken, was while(1) { ... } eigentlich macht.

    Und zu dem zweiten Parameter. Schau doch einfach in die Manpage zu man: sigaction 🙄



  • Ok, hat sich erledigt. Waren mal wieder Tomaten auf den Augen. Bitte um Nachsicht.

    #include <stdio.h>
    #include <unistd.h>
    #include <time.h>
    #include <sys/types.h>
    #include <stdlib.h>
    #include <signal.h>
    
    int main()
    {
       pid_t pid_1;
       pid_t pid_2; 
       int i = 5;
       int n = 98;
    
       time_t timer;
    
       pid_1 = fork();
    
       /*Sohnprozess*/
    
       if(pid_1 == 0) {
    
          sleep(15);      
          exit(0);   
    
       /*Vaterprozess*/
    
       } else if (pid_1 > 0) {
    
       pid_2 = fork();
    
       if(pid_2 == 0) {
    
       	  while(1) {
       	     n+i;
       	  }
       }
       kill(pid_2, SIGKILL);
    
       printf("PID Vater : %d\n", (int) getppid());
       printf("PID Sohn 1: %d\n", pid_1);
       printf("PID Sohn 2: %d\n", pid_2);
    
       printf("Zeit: %s\n", asctime(localtime(&timer)));
    
       system("ps -H");
       exit(0);
    
       }
    return 0;
    }
    

Anmelden zum Antworten