问题
* SOLUTION IN THE ANSWER BELOW *
I got a problem with limiting childs in the multifork php script... Seems like last child never ends... I'm really tired and can't find the error, could You please help? It does not end most of times...
<?php
declare(ticks = 1);
$max=5;
$child=0;
function sig_handler($signo) {
global $child;
switch ($signo) {
case SIGCHLD:
$child -= 1;
echo "[-]";
}
}
pcntl_signal(SIGCHLD, "sig_handler");
$found = array(1,2,3,4,5,6,7,8,9,10,11,12);
echo "LETS GO!\n";
foreach($found as $item){
while ($child >= $max) {
sleep(1);
}
$child++;
echo "[+]";
$pid=pcntl_fork();
if($pid){
}else{ // CHILD
sleep(rand(1,5));
echo "[~]";
exit(0);
}
}
while($child != 0){
echo "($child)";
sleep(1);
}
echo "THE END.\n"
?>
Result most times is:
[+][+][+][+][+][~][-][+][~][-][+][~][-][+][~][-][+][~][-][+][~][-][+][~][~][~][-][+] (5)[-](4)(4)[~][-](3)[~][-](2)(2)[~](2)[-](1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)... etc etc ...
Seems like last child does not end at all or at least it doesnt trigger sig handler...
- [+] <- just before forking - count: 12
- [~] <- just before child exit - count: 12
- [-] <- sig handler after child exit - count: 11
Help?
PS. The weird thing is that it sometimes does end.
回答1:
Ok found the solution:
function sig_handler($signo){
global $child;
switch ($signo) {
case SIGCLD:
while( ( $pid = pcntl_wait ( $signo, WNOHANG ) ) > 0 ){
$signal = pcntl_wexitstatus ($signo);
$child -= 1;
echo "[-]";
}
break;
}
}
The problem was in the way of handling signals on UNIX systems. All sigs sent in similar time are being grouped to one. The function above fixes that problem. And not only that one... when child exits immediately, it doesn't segfault ("zend_mm_heap corrupted" error in some PHP configurations/versions) anymore. And it did in previous case.
PS. I should delete this question, but I will leave the solution for everyone experiencing similar problems as multithreading in PHP scripts is very useful for some tasks.
来源:https://stackoverflow.com/questions/17526509/php-fork-limit-childs-in-the-task