Newsgroup: it.comp.os.linux.development
Titolo: processi defunct... mi perdo un sigchild?

sto facendo un applicativo (daemon) che ripete all'ģinfinito un ciclo
bloccandosi sull'attesa di un evento...  quando succede esegue la
funzione rispondi...  la quale forke tre volte per eseguire tre
programmi in serie
void rispondi()
{
        int pid,pid2,null;
        null=open("/dev/null");
        close(1);
        dup(null);
        if (fork()==0)
        {
 
                execl("comando1");
                exit();
        }
        wait();
        if (fork()==0)
        {
 
                execl("comando2");
                exit();
        }
        wait();
        if (fork()==0)
        {
 
                execl("comando3");
                exit();
        }
}
in queste condizioni a volte qualche "comando" si incepppa per qualche
motivo...  e diventa defunct...
ho il sospetto che sia legato al fatto che  non aspettando l'untima
fork il ciclo principale riprende...  viene eseguito un nuovo comando
e dopo qando arriva un sigchild qualcosa va storto...
infatto se aggiungo una wait in fondo (serializzando tutto)
....
 if (fork()==0)
        {
 
                execl("comando3");
                exit();
        }
wait();
}
il problema non sembra presentarsi...
se non ricordo male si dovrebbe agggirare la cosa con un handler...
ma non ho lo stevens sotto mano...   qualche tips?
tia


Se ho capito bene non ti interessa sapere quando i figli muoiono:
signal(SIGCHLD,SIG_IGN);
Cosi' ignori il segnale SIGCHLD e
NON devi fare le wait.
Ciao,
Ema



mi sono accorto...  per come  l'ho fatto io il padre e' bloccato sui
due comandi principali....  che sono serializzati assieme al terzo...
tantovale che aspetti pure il terzo...
quando puoi funziona sblocchero' il padre da subito...  
pero' mi chiedo...  lui non deve aspettare la serie dei tre comandi..
quiindi signal e' ok...
ma i tre figli si devono aspettare...  devo resettare l'handler oppure
l'exec cambiando l'area codice risolve la cosa?
ps...  mi manca lo
stevens!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!  sono
disperato!!!

 l'exec cambiando l'area codice risolve la cosa?
Non ho ben capito.
Allora, per quanto ne so io le cose corrette da fare possono essere:
1) Serializzazione dei comandi.
    Eseguire una fork e successivamente una wait. Cioe', una wait per ogni
fork!
2) Ignorare i figli (quello che tio ho gia' detto).
    signal(SIGCHLD,SIG_IGN);
    In questo modo non devi fare nessuna wait. Fai solo le fork e te ne
strafreghi dei figli.
3) Usare un gestore per il segnale SIGCHLD.
    void chld_hdlr(int segnale) {
        int stato, pid;
        /* Aspetto tutti i figli morti (possono essere piu' di uno) */
        while ((pid=waitpid(-1,&status,WNOHANG)) > 0) {
            ...
        }
        if (pid == -1) { /* C'e' stato un errore */ }
        if (pid == 0) { /* Non c'erano piu' figli da aspettare */ }
    }
    signal(SIGCHLD, chld_hdlr);
Nel caso 1 ti interessa aspettare il figlio appena lanciato per sapere
quando termina, evidentemente.
Nel caso 2 non ti interessa aspettare i figli.
Nel caso 3 ti interessa aspettare i figli, ma non nell'ordine con cui li hai
lanciati, per sapere chi e' terminato.
A seconda di quello che devi fare, scegli una delle tre soluzioni.
Ciao,
Ema