Anzeige:
Ergebnis 1 bis 5 von 5

Thema: fork, signal problematik

  1. #1
    Registrierter Benutzer Avatar von klewan
    Registriert seit
    06.05.2005
    Ort
    Wien
    Beiträge
    99

    fork, signal problematik

    hallo, ich hab in etwa folgenden code



    Code:
    int running;
    void sched_reaper(int signum) {
            int status;
            while (waitpid (-1, &status, WNOHANG) > 0) {
    	 		 	
    	 }
    	running--;
    }
    
    
    running=0;
    signal(SIGCHLD, reaper);
    for(x=0; x<10; x++) {
            child_pid=fork();
            switch(child_pid) {
    	   case -1:
              	  _log("FORK Error");
    	           return -1;
    	 break;
            	case 0:
                            signal(SIGCHLD, reaper);
                            //bisschen code
                            exit(0);
                    break;
    
             default:
                       running++;
                     
    
    }
    while(running != 0) {
          printf("waiting...");
    }
    mein problem is das dies zu 99.9% gut geht aber ab und an wird anscheinend kein sigchld ausgelöst, dann wenn der child-code irgendwie abkackt (externer code) den ich mal, was dann zu folge hat das "running" z.b.: 1 ist obwohl kein process mehr läuft


    meine frage:
    im gdb hab ichs nicht gebacken bekommen fork()'s zu debuggen, bzw die signal's zu sehen, irgend eine idee?

    welche signal's muss ein child abfangen, ich denk da z.b. an den fall das der child code segfault'ed (sollt zwar nicht sein, aber ist externer code)
    Geändert von klewan (01-05-2006 um 11:59 Uhr)

  2. #2
    Registrierter Benutzer
    Registriert seit
    02.07.2004
    Beiträge
    456
    Auch bei 'nem SegFault sollte (Developer's Best Friend: "Sollte eigentlich gehen") immer ein SIGCHLD im Parent aufschlagen.

  3. #3
    Registrierter Benutzer Avatar von klewan
    Registriert seit
    06.05.2005
    Ort
    Wien
    Beiträge
    99
    hmmmmpf
    wie kann dann ne abweichung, also nicht 0, in current_running rauskommen

    wie kann man man das SIGCHLD verhindern? (ähhh ungewollt *fg*)

  4. #4
    Registrierter Benutzer
    Registriert seit
    05.09.2002
    Ort
    Neuhausen
    Beiträge
    320
    Zitat Zitat von klewan
    mein problem is das dies zu 99.9% gut geht aber ab und an wird anscheinend kein sigchld ausgelöst, dann wenn der child-code irgendwie abkackt (externer code) den ich mal, was dann zu folge hat das "running" z.b.: 1 ist obwohl kein process mehr läuft
    Hmm, könnte es sein, dass ein Signal verlohren get? Dann würde allenfalls POSIX 1003.1b Signale helfen. (siehe sigaction). Zudem überprüfst du den Rückgabewert von waitpid() nicht auf Fehler (-1, siehe manpage).

    Code:
    while(running != 0) {
          printf("waiting...");
    }
    Hier ist es sicherer auf running <= 0 zu prüfen.

    Eine Alternative zu dem SIGCHLD Signal-Handler könnte in diesem Fall auch sein, dass du dieses Signal default-mässig ignorierst und stattdessen mit waitpid(-1, ..., WNOHANG); so lange wartest, bis alle gestarteten Prozesse sich beendet haben. Entweder du dekrementierst dabei wie gehabt running, oder du führt explizit eine Liste von child-pids und wartest mit waitpid(childpids[n], ..., WNOHANG) auf jeden Prozess einzeln. Ich empfehle WNOHANG, da sonst Zombies entstehen.

    meine frage:
    im gdb hab ichs nicht gebacken bekommen fork()'s zu debuggen, bzw die signal's zu sehen, irgend eine idee?
    Eigentlich müsste das mit "set follow-fork-mode child" funktionieren, leider ist diese Funktion ing gdb irgendwie nicht implementiert. Ich behelfe mir damit, dass ich nach dem fork() ein sleep(30) einfüge, um genug Zeit zu haben, mit gdb auf die neue pid zu attachen.

    welche signal's muss ein child abfangen, ich denk da z.b. an den fall das der child code segfault'ed (sollt zwar nicht sein, aber ist externer code)
    Das child muss keine speziellen Signale abfangen. Natürlich ist es immer sinnvoll, bei einem SIGTERM noch sauber aufzuräumen. SIGSEGV abzufangen mach selten Sinn, hier sollte auf jeden Fall beendet werden, und vor allem eine Programminternen Strukturen mehr angefasst werden. Ich habe z.B. ein System, bei dem einige Prozesse mit waitpid(-1, &status, WNOHANG) überwacht werden, und im Fehlerfall neu gestartet werden. In diesem übergeordneten Prozess überprüfe ich über die "status"-Variable, ob der Prozess mit SIGSEGV beendet worden ist und logge dieses Ereigniss.

    Gruss, Andy

  5. #5
    Registrierter Benutzer Avatar von klewan
    Registriert seit
    06.05.2005
    Ort
    Wien
    Beiträge
    99
    [edit]
    meld mich wieda wenn ich die manpage verstanden hab ;-D
    [/edit]
    Geändert von klewan (05-05-2006 um 13:38 Uhr)

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •