Newsgroup: it.comp.os.linux.sys
Titolo: [multi post abbestia] php e problemi con fork/wait

visto che non mi risponde nessuno ho deciso di fare giorno giorno la
domanda in un ng diverso, ormai ho quasi finito la gerarchia it!!! :)
problema: devo fare uno script php che forka e fa fare ai figli(tanti)
una determinata operazione (la stessa, ma su target diversi)
le funzioni che mi servono sono quindi le pcntl_fork/wait/waitpid/signal
eccetera.
Fatto un primo programmino di test per vederne il funzionamento mi sono
trovato in una situazione che proprio non riesco a capire:
alcune volte succede che la wait del padre non riesce a catturare per bene
i pid dei figli morti ( torna -1 al posto del pid), in particolar modo
questo accade quando:
1)- i figli sono già morti quando il padre si mette in wait
2)- 2 o più figli muoio "quasi" contemporaneamente
Ecco,questo è il problema.
Ma la cosa curiosa è che questo succede solo se il programma gira su
determinati ambienti!
queste sono le prove fatte da me:
slackware 12 , kernel 2.6.21 , php 5.2.qualcosa => il problema c'è.
slackware 11 , kernel 2.6.17 , php 4.3.10 => il problema c'è.
slackware 10.2 , kernel 2.6.13 , php 4.4.0 => il problema c'è.
debian etch kernel 2.6.18,  php 5.2.0 => il problema NON c'è
ubuntu QUALCOSA kernel 2.6.20 , php 5.2.1 => il problema NON c'è
ecco queste sono le distro che avevo a disposizione per fare le prove, e
sembrerebbe che il problema dipenda dalla DISTRO e non dalle versioni del
software! bah mi sembra incredibile pero' non so dove andare a parare ,
forse in slackware non vengono spuntate di default determinate opzioni del
kernel? (non credo perchè altrimenti avrei problemi sulle fork in
generale, mentre lo stesso programma fatto in C o python funziona
perfettamente)
Non so veramente a quale santo rivolgermi per capire cosa succede. 
Riporto anche lo script,, se avete voglia di provarlo su una qualche
distro diversa da quelle che ho elencato magari viene fuori qualcosa.
Grazie in anticipo:
ah, commentare/decommentare la sleep sul figlio fa in modo di passare
dalla situazione 1) alla 2) descritte sopra
#!/usr/bin/php
<?php
$children = array(); 
function child($id)
{
	$p=posix_getpid();
	echo "child: ($id) pid ($p)\n";
	//sleep(rand(1,5));
	echo "child:end pid ($p)\n";
	exit(0);
}
$i=0;
while($i<10)
{
	$pid = pcntl_fork();
	if($pid == -1)
		die("Could not fork!");
	elseif($pid == 0)
		 child($i);
	else
	{
		$children[$pid] = $i;
		$i++;	
	}	
}
print "dad:sleep a bit...\n";
$i=10;
while($i)
{
	$pid_dead = pcntl_waitpid(-1,$status);
	echo "dad:dead child pid ($pid_dead) \n";
	if(isset($children[$pid_dead]))
		unset($children[$pid_dead]);
 
	$i--;
}
echo "\ndad: Figli non correttamente aspettati:\n";
print_r($children);			
?>

ops , sbagliato gruppo, qua avevo già chiesto :)

 trovato in una situazione che proprio non riesco a capire:
avevo avuto anch'io un problema simile
ne avevo concluso che php ha problemi quando deve forcare un numero grande
di processi in poco tempo
nota anache che se il processo figlio è già morto al momento in cui il padre
di mette in attesa, è naturale che pcntl_waitpid ritorni -1

 di mette in attesa, è naturale che pcntl_waitpid ritorni -1
non mi risulta, il figlio diventa zombie, ma il pid dovrebbe essere
comunque tracciabile (negli ambiaenti in cui lo script funziona infatti
succede così. e succede così anche se lo script è in python e c)
ciao Aioe

 ubuntu QUALCOSA kernel 2.6.20 , php 5.2.1 => il problema NON c'è
Tutte installate sulla stessa macchina?

 Tutte installate sulla stessa macchina?
no, le tre slack su tre macchine diverse, la etch gira sotto qemu (e
l'ho provata su almeno 2 macchine), la ubuntu su un'altra macchina ancora

 succede così. e succede così anche se lo script è in python e c)
sembra un problema di glibc
nota che slack usa una versione più vecchia degli altri
ripeti la prova tenendo traccia della versione di glibc utilizzata
just my 5 cents

 nota che slack usa una versione più vecchia degli altri
P.S.
Digressione per un ignorante :P
il problema in questo caso lo avrebbe perche' ha usato quelle 
determinate glibc in fase di compilazione di php, giusto ?
Oppure vengono chiamate in causa anche durante il funzionamento ?
Sorry per l'ignoranza ma di certe cose proprio non ne so 'na cippa :(
Grazie
Rizio

 just my 5 cents
non erano 2 i cents? :-)

 Oppure vengono chiamate in causa anche durante il funzionamento ?
eh, qua si entra nella famosa valle di lacrime:
http://www.google.it/search?hl=it&q=librerie+statiche+dinamiche&btnG=Cerca+con+Google&meta=

 e poi: va bene che usa versioni vecchie di glibc ... ma anche la 12? bah
sdlack 12 usa glibc 2.5 (cioè vecchia)

 2)- 2 o più figli muoio "quasi" contemporaneamente
prova ad inserire uno "sleep" all'inizio dei processi child
oppure ad usare un qualche tipo di semaforo che il padre
tenga bloccato e che sblocchi solo dopo la creazione di
tutti i children, in tal modo il padre avrà tempo di creare
tutti i vari sottoprocessi e di acquisirne correttamente il
PID evitando o quantomeno riducendo il problema

 ha scritto:

Evviva Debian Sid :)
$ dpkg -l libc6|grep ^ii
ii  libc6                   2.7-6         GNU C Library: Shared libraries
$ 
-- 
 . ''`.  Debian maintainer | 
http://wiki.debian.org/DavidPaleino
 : :'  : Linuxer #334216 --|-- 
http://www.hanskalabs.net/
 `. `'`  GPG: 1392B174 ----|---- 
http://snipr.com/qa_page
   `-   2BAB C625 4E66 E7B8 450A C3E1 E6AA 9017 1392 B174

 $
ehm... anche slackware-current e' alla glibc 2.7-6...
ilSimo
-- 
now playing: Ozzy Osbourne - Crazy Train
Mordor
dark land under Sauron's spell
threatened a long time
threatened a long time
                                Blind Guardian - Lord Of The Rings



sì, in questo modo lo so che funziona, il problema è: perchè non
funziona nell'altro modo e solo in php e solo nella slackware?
sempre più BAH!

 $
eh, ma visto che lo script gira pefettamente anche su debian etch 
che gira con le libc6 2.3.6 .... direi che la soluzione sta da un'altra
parte :)

 parte :)
no redde...
questo genere di problemi è fortemente dipendente dalla versione della glibc
probabilmente solo alcune sottoversioni presentano il problema (tipo la
2.5.1 si e la 2.5.3 no)
se fosse così semplice, il betatesting non sarebbe una dura arte