Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (GNU/Linux, *NIX, *BSD und Co) » Prozess zum daemon machen

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ]
000
30.03.2009, 11:49 Uhr
~bsok
Gast


hi,

hab hier folgendes Beispiel, wobei ich dachte das hier meinen child prozess zum daemon mache

C++:
#include  <stdio.h>
#include  <sys/types.h>

#define   MAX_COUNT  200

void  ChildProcess(void);                /* child process prototype  */
void  ParentProcess(void);               /* parent process prototype */

int  main(void)
{
     pid_t  pid;

     pid = fork();
     if (pid == 0)
          ChildProcess();
     else
          ParentProcess();
    
     return 0;
}

void  ChildProcess(void)
{
   while(1)
   {
    printf("Ich bin das child und renn im endlos loop\n");
    sleep(10);
   }
}

void  ParentProcess(void)
{
     int   i;

     for (i = 1; i <= MAX_COUNT; i++)
          printf("This line is from parent, value = %d\n", i);
     printf("*** Parent is done ***\n");
}



Wenn da ausführe klappt es im ersten momen scheinbar, aber sobald der ChildProcess anfängt die textausgabe zu machen krieg ich die wieder auf die interaktive session. das ist nach meiner empfindung her falsch. wie krieg ich das hin, das die textaufgabe nicht auf dem terminal rauskommt wo ich das programm gestartet hab?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
30.03.2009, 12:04 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


naja dann musst du von deinem child die ausgabe umleiten. Das es da rauskommt, von wo aus du es gestartet hast ist ja logisch - wo sollte denn das child sonst hinschreiben? Es erbt schließlich alle(!) filehandles vom parent.
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
30.03.2009, 13:22 Uhr
0xdeadbeef
Gott
(Operator)


Du musst mindestens noch setsid() aufrufen, um dich von der Parent-Session zu lösen, außerdem empfiehlt sich das Wechseln in ein Verzeichnis, bei dem es keinen Unterschied macht, ob es gelockt wird und das Umleiten der Ein/Ausgabeströme, wie FloSoft richtig bemerkt.

Eine einfache Anleitung findest du zum Beispiel hier: www.theorie.physik.unizh.ch/~dpotter/howto/daemonize
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
30.03.2009, 19:55 Uhr
~bsok
Gast


danke für den link

wenn mein kind fertig ist, hab ich ein defunct - zombie process in meiner processliste.

Hab jetzt im parent einfach das Signal für das Child auf ignore gesetzt. Ist das ok das zu machen odr ist das ein quick&dirty way der nebenwirkungen haben kann? (prinzipell ist mein parent nicht angewiesen zu wissen wann sein kind stirbt)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
30.03.2009, 20:39 Uhr
0xdeadbeef
Gott
(Operator)


Ein Zombie ist ein Prozess, der beendet, aber noch nicht "geerntet" (wörtliche Übersetzung) ist. Damit er verschwindet, muss der Vaterprozess per wait(2) den Rückgabestatus abfragen.

Die Idee eines Daemons ist, dass der Vaterprozess sich sofort beendet, so dass init die Kontrolle über den Kindprozess übernimmt. init macht im Grunde nach dem Booten nicht viel mehr, als per wait beendete Prozesse zu ernten.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
01.04.2009, 13:32 Uhr
~bsok
Gast


ok,

hab mich verguckt.

Situation ist folgende.

deamonize funktioniert, das child das dann als background prozess läuft ist ein server der anfrgen annimmt. jede anfrage wird als seprates child bearbeitet. Wenn dieses chid dann fertig ist - dann entsteht ein zombie-eintrag.

bedeutet wait() das mein prozess darauf wartet das mein child prozess fertig ist? (als server wär das ja fatal) oder heist das nur das ich eine antwort erwarte?

wäre es prinzipell ein problem sollte anstehenden "ungeerntete" tote kinder im parent mit der ignorierung des entsprechenden prozesses zu lösen?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
01.04.2009, 14:01 Uhr
0xdeadbeef
Gott
(Operator)


Du solltest die Zombies schon reapen, ja. Es gibt mehrere Möglichkeiten damit umzugehen, die wohl üblichsten sind entweder SIGCHLD abzufangen und wait in einem Signalhandler auszuführen, etwa so:

C++:
void sighandler_child(int sig) {
  int *status;

  while(waitpid(-1, &status, WNOHANG) != -1);
}

// ...

signal(SIGCHLD, sighandler_child);


...ein einfacher wait-Call reicht hier nicht, weil SIGCHLD auch geschickt wird, wenn das Kind gestoppt, aber nicht beendet wurde. Die andere übliche Methode ist, für jedes Kind im Vater einen Thread aufzumachen, der dann auf den Kindprozess wartet.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
05.04.2009, 17:06 Uhr
~bsok
Gast


also wäre das hier jetzt ein brauchbares daemonize beispiel:


C++:
#include  <stdio.h>
#include  <sys/types.h>
#include  <sys/wait.h>
#include  <signal.h>

#define   MAX_COUNT  200

void  ChildChildProcess(void);                /* child process prototype  */

void sighandler_child(int sig)
{    
    int  status;
    while(waitpid(-1, &status, WNOHANG) != -1)
    ;
}

int  main(void)
{
     pid_t  pid, sid;
    
     signal(SIGCHLD, sighandler_child);

     pid = fork();
    
     if(pid < 0)
         exit(1);
     else if (pid == 0) /* neues parent aka child */
     {
        umask(0);
        sid = setsid();
        if (sid < 0)
            exit(1);
            
        if ((chdir("/")) < 0)
            exit(1);
            
        freopen( "/dev/null", "r", stdin);
        freopen( "/dev/null", "w", stdout);
        freopen( "/dev/null", "w", stderr);
        
        while(1)
        {
            pid = fork();
        
            if(pid < 0)
                return 1;
                
               if(pid==0)
                   ChildChildProcess();
                  
               sleep(10);
                  
           }
        
      

     }
     else
          return 0; /* interaktives Parent beenden */
    
     return 0;
}

void ChildChildProcess(void)
{
    printf("ChildChild is jetzt fertig");
    sleep(2);
    exit(1);
}    

 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
05.04.2009, 17:30 Uhr
0xdeadbeef
Gott
(Operator)


Du hast ein paar Header vergessen (sys/stat.h für umask, unistd.h für fork etc, stdlib.h für exit), aber ansonsten kann man das so machen, ja.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
06.04.2009, 10:35 Uhr
~bsok
Gast


ok danke

gibt es einen qualitativen Unterschied zwischen der oben gepostet variante und dem "doppelten forken".

Ich bin beim googlen relativ oft darauf gestoßen. Ich seh ich da keinen qualitativen Unterschied.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ C / C++ (GNU/Linux, *NIX, *BSD und Co) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: