Re: Re: Fork and zombies

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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
> 


-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php


[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux