Windows — 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 функция и все работает просто отлично.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]