2015-01-14 3 views
1

В настоящее время я разрабатываю структуру развертывания в PHP и получаю некоторые проблемы с потоками и потоками.PHP: сбой потока при чтении потока потока

Я хочу начать процесс, прочитать его stdout и stderr (отдельно!), Эхо и вернуть полное содержимое потоков при завершении процесса.

Чтобы получить этот функционал, я использую два потока, каждый из которых читает другой поток (stdout | stderr). Теперь проблема, с которой я столкнулся, заключается в том, что php сбой, когда fgets получает вызов во второй раз. (Код ошибки 0x5, смещение ошибки 0x000610e7).

После многих ошибок и ошибок я понял, что когда я добавляю фиктивный массив в функцию run, авария не всегда происходит, и она работает так, как ожидалось. У кого-нибудь есть идея, почему это происходит?

Я использую Windows 7, PHP 5.4.22, MSVC9, Pthreads 2.0.9

private static $pipeSpecsSilent = array(
    0 => array("pipe", "r"), // stdin 
    1 => array("pipe", "w"), // stdout 
    2 => array("pipe", "w")); // stderr 

public function start() 
{ 
    $this->procID = proc_open($this->executable, $this::$pipeSpecsSilent, $this->pipes); 
    if (is_resource($this->procID)) 
    { 
     $stdoutThread = new POutputThread($this->pipes[1]); 
     $stderrThread = new POutputThread($this->pipes[2]); 
     $stderrThread->start(); 
     $stdoutThread->start(); 

     $stdoutThread->join(); 
     $stderrThread->join(); 

     $stdout = trim($stdoutThread->getStreamValue()); 
     $stderr = trim($stderrThread->getStreamValue()); 

     $this->stop(); 
     return array('stdout' => $stdout, 'stderr' => $stderr); 
    } 
    return null; 
} 

/** 
* Closes all pipes and the process handle 
*/ 
private function stop() 
{ 
    for ($x = 0; $x < count($this->pipes); $x++) 
    { 
     fclose($this->pipes[$x]); 
    } 

    $this->resultValue = proc_close($this->procID); 
} 


class POutputThread extends Thread 
{ 
    private $pipe; 
    private $content; 

    public function __construct($pipe) 
    { 
     $this->pipe = $pipe; 
    } 

    public function run() 
    { 
     $content = ''; 

     // this line is requires as we get a crash without it. 
     // it seems like there is something odd happening? 
     $stackDummy = array('', ''); 

     while (($line = fgets($this->pipe))) 
     { 
      PLog::i($line); 
      $content .= $line; 
     } 
     $this->content = $content; 
    } 

    /** 
    * Returns the value of the stream that was read 
    * 
    * @return string 
    */ 
    public function getStreamValue() 
    { 
     return $this->content; 
    } 
} 

ответ

1

я нашел проблему:

Хотя я закрываю потоки после всех потоков прекращено кажется, что требуется закрыть поток внутри потока, который читал из него. Итак, я заменил вызов $this->stop();fclose($this->pipe); внутри функции run, и все работает отлично.

 Смежные вопросы

  • Нет связанных вопросов^_^