Newsgroup: it.comp.lang.perl
Titolo: waitpid non bloccante

Ciao a tutti,
Secondo voi � corretto quanto scritto in
http://perldoc.perl.org/functions/waitpid.html
 ??
Io per far funzionare waitpid non bloccante su slackware e debian devo
sostituire il while con l'until, in quanto waitpid mi restituisce 0 finch�
il processo figlio � in esecuzione...
-- 
g4b0, linux user n. 369000
http://gabo.homelinux.com

 il processo figlio � in esecuzione...
Probabilmente, tu chiami waitpid su un determinato pid e continui a iterare
finch� il valore restituito non � maggiore di 0, cio� quando il figlio in
questione � uscito. (Attenzione, che questo crea un loop "stretto", che
consuma CPU inutilmente, soprattuto se il figlio ci mette un po' ad
uscire.)
L'esempio in questione chiama waitpid con -1, e continua a iterare finch� il
valore restituito non � minore o uguale a zero. Questa condizione si
verifica quando tutti gli zombi sono stati "raccolti".
Max

 verifica quando tutti gli zombi sono stati "raccolti".
Il codice � il seguente, si tratta di un semplice script per testare il
fork:
#########################################################
#!/usr/bin/perl -w
use POSIX ":sys_wait_h";
my $pid = fork();
if (not defined $pid) {
        print "resources not avilable.\n";
} elsif ($pid == 0) {
# processo figlio
        print "IM THE CHILD - $pid\n";  
        $i = 5;
        while ($i-- > 0){
                sleep(1);
                print("B $i\n");
        }
        exit(0);
} else {
# processo padre 
        print "IM THE PARENT - $pid\n";
        do {
                $kid = waitpid(-1, WNOHANG);
                sleep(1);
                print("A $kid\n");
   } until $kid > 0
}
print "Bye\n";
#########################################################
Ed il risultato � ci� che mi aspetto:
bash-3.1$ ./testFork.pl
IM THE PARENT - 4781
IM THE CHILD - 0
A 0
B 4
A 0
B 3
A 0
B 2
A 0
B 1
A 0
B 0
A 0
A 4781
Bye
bash-3.1$
Se sostituisco l'until con il while, ottengo il seguente output:
bash-3.1$ ./testFork.pl
IM THE PARENT - 4783
IM THE CHILD - 0
B 4
A 0
Bye
bash-3.1$ B 3
B 2
B 1
B 0
bash-3.1$         


 
Le due varianti del loop implementano logiche diverse. La seconda, che �
quella che hai ripreso dall'esempio, attende finch� waitpid non restituisce
un valore minore o uguale a zero, ossia quando waitpid non rileva alcuno
zombie. Nel tuo caso, questo loop esce subito in quanto la prima volta che
waitpid viene invocato il figlio � ancora in esecuzione e non ci sono altri
figli zombie.
La prima versione del loop, invece, attende finch� waitpid non � uscito con
un valore maggiore di zero, ossia quando waitpid ha riscontrato che almeno
un figlio � uscito. In questo caso, il loop termina quando il figlio esce.
L'esempio della documentazione serve a "raccogliere" tutti i figli che in
quel momento risultano gi� morti (zombie) senza bloccarsi nell'attesa che
qualcuno muoia. La tua versione, invece, attende la morte di almeno un
figlio. Nessuna delle due � sbagliata: svolgono compiti differenti.
Max

 #########################################################
Di solito waitpid() non bloccante la si chiama nell' handler
del signal SIGCHLD
esempi in perldoc perlipc
use POSIX ":sys_wait_h";
sub REAPER {
   my $child;
   # If a second child dies while in the signal handler caused by the
   # first death, we won't get another signal. So must loop here else
   # we will leave the unreaped child as a zombie. And the next time
   # two children die we get another zombie. And so on.
   while (($child = waitpid(-1,WNOHANG)) > 0) {
      $Kid_Status{$child} = $?;
   }
   $SIG{CHLD} = &REAPER;  # still loathe sysV
}
$SIG{CHLD} = &REAPER;
# do something that forks...
Per come la usi tu al contrario sarebbe meglio bloccante.
Ciao
Roberto
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it