PHP использует proc_open, чтобы он не ждал завершения скрипта, который он открывает (запускает)? - PullRequest
0 голосов
/ 06 августа 2010

Я потратил некоторое время на это, но не могу заставить это работать, я извиняюсь, поскольку я задал несколько связанный вопрос об этом ранее, но удалил его, чтобы я мог провести больше исследований, чтобы сузить вопрос, на данный моментЯ застрял, как я думал, у меня есть решение с этим, но оно не работает, как я ожидаю .. Я нашел форум, где кто-то задал похожий вопрос, и они дали код, как показано ниже, который я пытаюсь .. он запускает скрипт,но он все еще ждет завершения, прежде чем перейти к следующей строке в коде PHP

    proc_close(proc_open ("/var/www/other_scripts/perl/apps/emails_extract_from_url.pl \"$stoopid\"", array(), $foo));

Ответы [ 3 ]

3 голосов
/ 06 августа 2010

Привет, я в последнее время много использую proc_open, и он никогда не ждет, пока он закончит, прежде чем двигаться дальше. Убедитесь, что вы указали каналы, а не просто используете пустой массив ()

$descriptorspec = array(
   0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
   1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
   2 => array("file", "/tmp/error-output.txt", "a") // stderr is a file to write to
);

, а также присваивать proc_open переменной.

$myProc = proc_open("/var/www/other_scripts/perl/apps/emails_extract_from_url.pl \"$stoopid\"", $descriptorspec , $foo)

Затем вы можете получить статус вашего процесса, используя proc_get_status($myProc);

Больше информации здесь http://au.php.net/proc_open

Дополнительная информация о закрытии.

$temp = fgets($this->open_pipes[$thread_id][1], 1024);
if($this->checkFinishedThread($thread_id))
{
    fclose($this->open_pipes[$thread_id][1]);
    proc_close($thread);
}

function checkFinishedThread($thread_id)
{
    $test = stream_get_meta_data($this->open_pipes[$thread_id][1]);
    if($test['eof'] == 1)
        return true;
    return false;
}
0 голосов
/ 25 февраля 2016

Вам необходим амперснад (&) в конце аргумента командной строки:

proc_close(proc_open ("/var/www/other_scripts/perl/apps/emails_extract_from_url.pl \"$stoopid\" & ", array(), $foo)); 
0 голосов
/ 06 августа 2010

Часть моего кода, когда я играл с proc_open
У меня были проблемы с proc_close (от 10 до 30 секунд), поэтому я просто убил процесс с помощью команды linux kill



$options=array();
$option['sleep-after-destroy']=0;
$option['sleep-after-create']=0;
$option['age-max']=40;
$option['dir-run']=dirname(__FILE__);
$option['step-sleep']=1;
$option['workers-max']=(int)file_get_contents($maxworkers_file);
$option['destroy-forcefull']=1;

$workers=array();

function endAWorker($i,$cansleep=true) {
        global $workers;
        global $option;
        global $child_time_limit;
        if(isset($workers[$i])) {
                @doE('Ending worker [['.$i.']]'."\n");
                if($option['destroy-forcefull']==1) {
                        $x=exec('ps x | grep "php check_working_child.php '.$i.' '.$child_time_limit.'" | grep -v "grep" | grep -v "sh -c"');
                        echo 'pscomm> '.$x."\n";
                        $x=explode(' ',trim(str_replace("\t",' ',$x)));
                        //print_r($x);
                        if(is_numeric($x[0])) {
                                $c='kill -9 '.$x[0];
                                echo 'killcommand> '.$c."\n";
                                $x=exec($c);
                        }
                }
                @proc_close($workers[$i]['link']);
                unset($workers[$i]);
        }
        if($cansleep==true) {
                sleep($option['sleep-after-destroy']);
        }
}

function startAWorker($i) {
        global $workers;
        global $option;
        global $child_time_limit;

        $runcommand='php check_working_child.php '.$i.' '.$child_time_limit.' > check_working_child_logs/'.$i.'.normal.log';
        doE('Starting [['.$i.']]: '.$runcommand."\n");
        $workers[$i]=array(
                'desc' => array(
                        0 => array("pipe", "r"),
                        1 => array("pipe", "w"),
                        2 => array("file", 'check_working_child_logs/'.$i.'.error.log', "a")
                        ),
                'pipes'                 => null,
                'link'                  => null,
                'start-time'    => mktime()
                );
        $workers[$i]['link']=proc_open(
                $runcommand,
                $workers[$i]['desc'],
                $workers[$i]['pipes'],
                $option['dir-run']
                );
        sleep($option['sleep-after-create']);
}

function checkAWorker($i) {
        global $workers;
        global $option;
        $temp=proc_get_status($workers[$i]['link']);
        if($temp['running']===false) {
                doE('Worker [['.$i.']] finished'."\n");
                if(is_file('check_working_child_logs/'.$i.'.normal.log') && filesize('check_working_child_logs/'.$i.'.normal.log')>0) {
                        doE('--------'."\n");
                        echo file_get_contents('check_working_child_logs/'.$i.'.normal.log');
                        doE('-------'."\n");
                }
                endAWorker($i);
        } else {
                if($option['age-max']>0) {
                        if($workers[$i]['start-time']+$option['age-max']$v) {
                endAWorker($i,false);
        }
        @doE('Done killing workers.'."\n");
}

register_shutdown_function('endAllWorkers');

while(1) {
        $step++;
        foreach($workers as $index=>$v) {
                checkAWorker($index);
        }
        if(count($workers)==$option['workers-max']) {
        } elseif(count($workers)$option['workers-max']) {
                $wl=array_keys($workers);
                $wl=array_pop($wl);
                doE('Killing worker [['.$wl.']]');
                endAWorker($wl[0]);
        }
}

...