Разветвление PHP: убивать ребенка, когда он становится зомби

У меня есть этот блок кода, который идеально подходит для моих нужд в моих различных программах php cli. За исключением того, что иногда ребенок становится зомби.

Мой вопрос в том, где разместить код, чтобы проверить, работает ли ребенок, скажем, 5 минут, а если дольше, то убить его?

Я знаю о posix_kill, чтобы убить его, и о том, как его отслеживать. Здесь есть примеры диспетчеров задач .

Я не уверен, как объединить эти новые функции в код. Каждый раз, когда я пытаюсь это сделать, я попадаю в беспорядок. Может быть, кто-нибудь, кто знает о разветвлении, может исправить мой код?

Игнорируйте все error_logs - мне нравится видеть, что происходит при его запуске.

public function __construct($data) {        
    //Keep track of all of the children processes
    $this->children = Array();

    //Specify the maximum number of child processes to fork at any given time
    $this->max_children = 5;
}

private function process()
{
    foreach ($collection as $stuff) 
    {
        //FORK THE PROCESS  
        $pid = pcntl_fork();

        //Something went wrong
        if($pid == -1) 
        {
            error_log ("could not fork");
            die ();
        }

        //PARENT PROCESS
        if($pid) 
        {
            //error_log ("Parent: forked " . $pid);
            $this->children[] = $pid;
        }
        //CHILD PROCESS
        else 
        {
            // Do stuff here                                                

            exit(); //Exit the child thread so it doesn't continue to process the data
        }

        //COLLECT ALL OF THE CHILDREN AS THEY FINISH
        while( ($c = pcntl_wait($status, WNOHANG OR WUNTRACED) ) > 0)
        {
            //error_log ("Collected Child - " . $c);
            $this->remove_thread($this->children, $c);

            error_log ("children left: " . count($this->children));
        }

        //WAIT FOR A CHILD TO FINISH IF MAXIMUM PROCESSES IS EXCEEDED
        if(sizeof($this->children) > $this->max_children)
        {
            //error_log ("Maximum children exceeded.  Waiting...");
            if( ($c = pcntl_wait($status, WUNTRACED) ) > 0)
            {
                //error_log ("Waited for Child - " . $c);
                $this->remove_thread($this->children, $c);

                error_log ("children left: " . count($this->children));
            }
        }
    }   

    //COLLECT ALL OF THE CHILDREN PROCESSES BEFORE PROCEEDING
    while( ($c = pcntl_wait($status, WUNTRACED) ) > 0){
        //error_log ("Child Finished - " . $c);
        $this->remove_thread($this->children, $c);

        error_log ("children left: " . count($this->children));
    }           
}

    //Function to remove elements from an array
private function remove_thread(&$Array, $Element)
{
    for($i = 0; $i < sizeof($Array); $i++)
    {
        //Found the element to remove
        if($Array[$i] == $Element){
            unset($Array[$i]);
            $Array = array_values($Array);
            break;  
        }
    }
}   

6
задан hakre 12 July 2012 в 16:45
поделиться