Hi
i have to develop a multihreaded php application on linux, then through
pcntl_fork and wait.
I tried it, but there something going wrong, i think.
The difference whit other languages like c and python is that the wait
cannot handle correctly all signals from dead children in two cases:
1 - two or more children dies (about) at the same time time
2 - the chidren dies before pcntl_wait start
in fact the wait does not return the chld's pid, but "-1"
that is he knows that a child is dead, but he cannot say the correct
pid.
I made two scripts (below), one php and one python that should do the same
thing. The python one run correctly , the php no.
You can verify their behaviour, if you want.
You can comment, o indecrease or increase the sleep call in the php script
to note what happend at the wait call
At the end i ask you, am i doing someting wrong?
Is the php fork/wait behaviour bugged?
thanks in advance
Andrea
#!/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++;
}
}
print "dad:sleep a bit...\n";
$i=10;
while($i)
{
$pid_dead = pcntl_waitpid(-1,$status);
if ($pid_dead != 0)
{
echo "dad:dead child pid ($pid_dead)\n";
if(array_search($pid_dead,$children))
{
unset($children[$pid_dead]);
print "dad:unset pid ($pid_dead)\n ";
$i--;
}
else
{
$i--;
print "dad:pid ($pid_dead) not tracked\n";
}
}
}
echo "dad: all dead\n"
?>
#!/usr/bin/python
import sys
import os
import time
def child(i):
print "child: (%d) pid (%d)" % (i,os.getpid())
sys.exit(0);
children=[]
i=0
while i<10:
i+=1
pid = os.fork()
if not pid:
child(i)
else:
children.append(pid)
print "dad:sleep a lot..."
time.sleep(2)
while len(children):
pid_dead = os.waitpid(-1,os.WNOHANG)
if pid_dead[0] != 0:
print "dad:dead pid (%d)" % pid_dead[0]
try:
children.index(pid_dead[0])
children.remove(pid_dead[0])
print "dad:eliminato pid (%d) " % pid_dead[0]
except:
print "dad:pid (%d) not in children" %
pid_dead[0]
time.sleep(0.5)
print "dad: all dead"