Re: Re: Fork and zombies
| From: | Jochem Maas | Date: | Tue, 17 Mar 2009 21:00:59 +0000 |
| Subject: | Re: Re: Fork and zombies | ||
| References: | 1 2 3 4 5 6 7 8 9 10 11 12 | Groups: | php.general |
| Request: | Send a blank email to php-general+get-290183@lists.php.net to get a copy of this message | ||
Per Jessen schreef:
> Waynn Lue wrote:
>
>> (Apologies for topposting, I'm on my blackberry). Hm, so you think
>> exiting from the child thread causes the db resource to get reclaimed?
>>
>
> Yeah, something like that. The connection is definitely closed when the
> child exits.
>
I can confirm this. you definitely need to open a connection for each child process.
if you require a db connection in the parent process, you should close
it before forking (and then reopen it afterwards if you still need it).
at least that's what I found I had to do when I ran into this.
incidently my forking loop looks like this, very interested to know if
Per can spot any obvious stupidity:
$childProcs = array();
do {
if (count($childProcs) <= $maxChildProcs) {
$site = array_shift($sites);
$pid = pcntl_fork();
} else {
// stay as parent, no fork, try to reduce number of child processes
$site = null;
$pid = null;
}
switch (true) {
case ($pid === -1):
cronLog("error: (in {$thisScript}), cannot initialize worker process in order to
run {$script} for {$site['name']}");
break;
case ($pid === 0):
// we are child
$exit = 0;
$output = array();
// do we want to exec? or maybe include?
if ($doExec) {
exec($script.' '.$site['id'], $output, $exit);
} else {
$output = inc($script);
$output = explode("\n", $output);
}
if ($exit != 0)
cronLog("error: (in {$thisScript}), {$script} reported an error ($exit) whilst
processing for {$site['name']}",);
foreach ($output as $line)
cronLog($line);
exit($exit);
break;
default:
// we are parent
$childProcs[] = $pid;
do {
$status = null;
while (pcntl_wait($status, WNOHANG | WUNTRACED) < 1)
usleep(50000);
foreach ($childProcs as $k => $v)
if (!posix_kill($v, 0)) // send signal 'zero' to check whether process
is still 'up'
unset($childProcs[ $k ]);
$childProcs = array_values($childProcs);
if (count($sites))
break; // more sites to run the given script for
if (!count($childProcs))
break; // no more sites to run the given script for and all children are
complete/dead
} while (true);
break;
}
if (!count($sites))
break; // nothing more to do
usleep(50000);
} while (true);
>
> /Per
>