Newsgroup: it.comp.lang.perl
Titolo: terminazione processi dopo fork()

salve a tutti!
in un programma di test che sto facendo ad un certo punto eseguo un 
for(1..$num) {
	my $pid = fork();
	if ($pid) { #padre colleziona i pid dei figli
		push(@childs, $pid);
....
e creo un certo numero di processi, ognuno che terminerà dopo un tempo
variabile.
per catturare il termine di ogni processo il padre esegue:
foreach (@childs) {
	print "padre - aspetto figlio pid: " . $_ . "\n";
	waitpid($_, 0);
}
ma il ciclo foreach procede un processo alla volta sequenzialmente e la
rilevazione del termine di alcuni processi è bloccata dal termine di un
processo dalla durata maggiore che viene scandito prima dal ciclo foreach.
domanda: come faccio a catturare la fine di uno qualsiasi dei processi
che ho avviato precedentemente? (senza dover attendere la fine di un altro)
grazie!!!
ar

 che ho avviato precedentemente? (senza dover attendere la fine di un altro)
definendo un handler per SIGCHLD come da esempi su perldoc perlipc:
l' esempio piu' funzionante e':
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...
questo handler lo devo modificare per gestire l' array globale di
collezione di pin pero' ... QUESTO LO RENDE NON RIENTRANTE!
quindi le parti di codice di accesso all array andranno protette
bloccando il segnale cosi':
use POSIX();
$tmpsigset = POSIX::SigSet->new;
$oldsigset = POSIX::SigSet->new;
$tmpsigset->emptyset();
$oldsigset->emptyset();
$tmpsigset->addset(&POSIX::SIGCHLD);
POSIX::sigprocmask(&POSIX::SIG_BLOCK, $tmpsigset, $oldsigset);
# codice dove accedi a @childs o in valutazione o in assegnazione.
POSIX::sigprocmask(&POSIX::SIG_SETMASK, $oldsigset, $tmpsigset);
Questo esempio usa il modello POSIX per bloccare un segnale senza perderlo
L' handler non verra' eseguito nel codice protetto che quindi potra'
valutere o modificare l' array @child senza che l' hander lo modifiche
imprevedibilmente a sua volta. Se il segnale sara' nel frattempo occorso,
il suo handler verra eseguito allo sblocco del segnale.
Se hai bisogno di aiuto per mettere insieme i due codici posta pure in NG.
ciao
Roberto.
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 Roberto.
wow grazie per la risposta molto elaborata! :)
nel frattempo ho risolto il problema con una cosa del genere:
while (($pidnum = wait()) > 0){
	print "padre ---- uscito figlio con pid: " . $pidnum . "\n";
	...
	doSomething($pidnum)
	...
}
Domanda: una soluzione semplice del genere mi comporta qualche conseguenza
nascosta?
una cosa che mi viene in mente è che mentre eseguo doSomething() se uno
più processi figli finiscono restano in attesa (zombie?...) fino a che non
rieseguo $pidnum = wait().
questi processi zombie che tipo di problemi possono creare?
grazie ancora!
saluti!!!
ar

 ar
direi che va bene. se il processo padre non deve fare altro nel frattempo
che aspettare l' estinzione dei figli e' sufficiente.
La soluzione che ho proposto io e' anche troppo prolissa e per impieghi
piu'
generali. Usa pure la tua soluzione se l' unico evento che interessa il
processo padre e' la exit di un figlio.
Magari ti interessa comunque avere a corredo anche la soluzione basata su
segnale, che ha molti altri impieghi e di solito piu' utile.
Il processo che ha chiamato exit e' gia' defunto e solo il suo codice
di ritorno deve essere letto dal padre. occupa una word, ma non mangia
risorse di sistema e non viene schedulato. se la wait non e' istantanea
non importa.
Ciao


 segnale, che ha molti altri impieghi e di solito piu' utile.
ti ringrazio delle risposte!
la soluzione con i segnali è interessante ma me la devo un pò da rivedere,
sono all'inizio con il perl e alcune cose non mi sono ancora molto chiare... :D
ciao ciao!!