Frage: Vater/Sohn - Zombie Prozess



  • So ich bins nochmal, diesmal angemeldet. 😃

    hmm ich versuche gerade ein Programm zu schreiben, indem der Sohn von 1 bis 10 hochzählt und wenn der Vatr auf enter drückt, soll sich der Sohn schließen.

    int main( int argc, char* argv[] ){
    pid_t pID = fork();
    
    if (pID < 0 ) { printf("FEHLER in FROK");}
    if (pID == 0) { printf("Child");
               int i;
               for (i=0; i<10; i++){
                    if (( pID != 'X') || ( pID != 'Z))
     {                  Printf(" Sleep %d Seconds\n", i);
                        Sleep (1);
     }  
     }
    }
    else {printf("Parent"); getchar();}}
    

    Der Sohn läuft aber immer noch weiter.

    Wo genau kann ich globale Variablen definieren? Einfach über der main()?
    Blicke das ganze nicht so durch.



  • abgesehen von den anderen Problemen in deinem Programm noch mal die Frage: läuft der Prozess mit PID xyz noch?

    im Verzeichnis /proc befindet sich für jeden Prozess ein Unterverzeichnis mit dem Namen seiner PID. in diesem Unterverzeichnis befindet sich eine Datei "stat", diese muß man öffen und lesen. um an die Info "process state" zu kommen, muß man erst mal die beiden davor liegenden Einträge überlesen, ungefähr so:

    bool isProcessRunning (int iProcessId)
      {
      char procId [64];
      sprintf (procId, "/proc/%d", iProcessId);
    
      if (access (procId, F_OK) != 0)
        return false;
    
      bool bRet = false;
      FILE * pStat;
      strcat (procId, "/stat");
    
      if ((pStat = fopen (procId, "r")) != 0)
        {
        int iChar = ' ';
    
        // Search end of (comm) entry
        while ((iChar != EOF) && (iChar != ')'))
          iChar = fgetc (pStat);
    
        if (iChar != EOF)
          {
          iChar = fgetc (pStat);
    
          while ((iChar != EOF) && (iChar <= ' '))
            iChar = fgetc (pStat);
    
          if (iChar != EOF)
            bRet = ((iChar != 'X') && (iChar != 'Z'));
          }
    
        fclose (pStat);
        }
    
      return bRet;
      }
    


  • Warum prüfst du pID in der for schleife auf irgendwelche chars pID wird doch gar nicht verändert.

    Nach erfolgreichem fork hast du zwei kopien des gleichen Prozesses nur fork gibt unterschiedliche Werte zurück (vereinfacht ausgedrückt).

    Der Rückgabewert eines Kind-Prozesses muss mithilfe von wait o.ä. abgefragt werden, dass geht nur wenn das Kind ein Zombie ist, also beendet wurde.

    Soweit ich das verstehe möchtetst du folgendes:
    Das Kind führt eine Endlosschleife aus
    Der Vater wartet auf die Eingabe von Enter auf der Stdin
    ->dann beendet er das Kind (zB ganz einfach per SIGKILL)
    ->gibt den Rückgabewert des Kindes aus
    beendet sich selbst

    Wichtig: der Speicher wird nicht geteilt, jeder Prozess hat seinen eigenen Speicher



  • 😕

    also mit ps -axlc
    kann man ja sehen, ob noch ein Programm ausgeführt wird oder nicht.
    Also dort ist nichts mehr zusehen.

    Mit dem Sohn, dass der noch läuft, meinte ich, dass nachdem ich auf Enter drücke und der Sohn tut noch immer hochzählen.

    Zurück zu meinem Problem.
    Ich müsste doch nur wissen, wie ich in der Sohn for Schleife abfragen kann, ob der Vater schon beendet wurde oder nicht.

    Soweit ich das verstehe möchtetst du folgendes:
    Das Kind führt eine Endlosschleife aus
    Der Vater wartet auf die Eingabe von Enter auf der Stdin
    ->dann beendet er das Kind (zB ganz einfach per SIGKILL)
    ->gibt den Rückgabewert des Kindes aus
    beendet sich selbst

    Wichtig: der Speicher wird nicht geteilt, jeder Prozess hat seinen eigenen Speicher

    Ja, genau das meinte ich. 🙂



  • SinnMeister schrieb:

    😕
    Zurück zu meinem Problem.
    Ich müsste doch nur wissen, wie ich in der Sohn for Schleife abfragen kann, ob der Vater schon beendet wurde oder nicht.

    Soweit ich das verstehe möchtetst du folgendes:
    Das Kind führt eine Endlosschleife aus
    Der Vater wartet auf die Eingabe von Enter auf der Stdin
    ->dann beendet er das Kind (zB ganz einfach per SIGKILL)
    ->gibt den Rückgabewert des Kindes aus
    beendet sich selbst

    Wichtig: der Speicher wird nicht geteilt, jeder Prozess hat seinen eigenen Speicher

    Ja, genau das meinte ich. 🙂

    Nein, meinst du nicht du hast doch oben was anderes geschrieben.

    Die Informationen die du gibst sind wiedersprüchlich und kaum zu gebrauchen.
    Du solltst dich ersteinmal mit den Grundlagen der Prozesse bschäftigen und die manpages der Funktionen komplett lesen und verstehen!
    Damit du dann zielführende Fragen stellen kannst, und es möglich ist dir zu helfen.



  • Wenn du das machen willst was ich geschrieben habe brauchst du:
    fork,wait,kill

    Was du geschrieben hast geht nicht den der Rückgabewert kann nur vom Elternprozess ausgelesen werden und damit wird der Zombie zerstört, eventuell noch laufende Kindprozesse verwaisen.



  • Ich frage mich ob das so überhaupt machbar ist,

    oder ob man auf pthread_create() angewiesen ist.

    Denn es ist scheinbar nicht möglich, mittels fork() den Status des Parent zu bekommen.

    Wenn man nämlich den Child terminiert, ließe sich zb. auch keine Meldung mehr erzeugen vom Child wie "Ich habe die Schleife verlassen";



  • Weder die funktion fork noch pthread_create wird dir auskunft über den Status des Parent geben, dafür sind sie auch nicht gedacht.

    Die Frage ist was genau willst du wissen und womit willst du es erreichen. Du kannst natürlich Informationen über den parent bekommen, nur was willst du erreichen und was darfst/willst du benutzen.
    Aber fork und pthread_create habe damit nichts zu tun sie sind nur dafür da einen Prozess bzw. thread zu erzeugen.



  • Der Parent-Prozess bekommt mit, wenn der Child-Prozess sich beendet. Der Child-Prozess nicht so ohne weiteres. Das macht man üblicherweise über eine pipe. Die Prozesse können sich eine pipe unterhalten. Wenn der Parent die Pipe beendet, dann kann der Child das fest stellen.

    Das ist sehr grob ausgedrückt. Details musst Du Dir halt anlesen.



  • so ist eine Weile her, aber alle die hier zufällig vorbeikommen sollen zumindest den richtigen Weg erläutert bekommen.

    man kann sowohl mit fork() als auch pthread_create ein Programm so schreiben, dass man im Parent oder Child weiß, wann der jeweils andere zueende geht.

    Wie geht das?

    Die einfachere Variante ist pthread_create, da legt man einfach eine globale varibale an und verändert diesen Wert vor dem Exit.

    Mit fork() geht das Prinzipiell genau gleich, hier gibt es aber keine globale Variablen, sondern muss dan Speicher im Adressraum zuteilen. Das ist eine etwas kniffligere Variante mit mehr Code.

    Was ich wollte? Das steht doch genau im ersten post 🙂 ⚠
    Hat sich jetzt aber erledigt^^



  • SinnMeister schrieb:

    so ist eine Weile her, aber alle die hier zufällig vorbeikommen sollen zumindest den richtigen Weg erläutert bekommen.

    man kann sowohl mit fork() als auch pthread_create ein Programm so schreiben, dass man im Parent oder Child weiß, wann der jeweils andere zueende geht.

    Wie geht das?

    Die einfachere Variante ist pthread_create, da legt man einfach eine globale varibale an und verändert diesen Wert vor dem Exit.

    Mit fork() geht das Prinzipiell genau gleich, hier gibt es aber keine globale Variablen, sondern muss dan Speicher im Adressraum zuteilen. Das ist eine etwas kniffligere Variante mit mehr Code.

    Ihr müsst natürlich noch ein Verfahren für wechselseitigen Ausschluss (auch Mutex genannt) für die Variable benutzen.
    Bei Threads volatile nicht vergessen.

    Hinweis: es gibt auch noch andere Lösungen für dieses Problem!


Anmelden zum Antworten