【问题标题】:PHP: thread crash when reading pipe streamPHP:读取管道流时线程崩溃
【发布时间】:2015-01-14 12:14:55
【问题描述】:

我目前正在用 PHP 开发一个部署框架,但遇到了一些关于线程和流的问题。

我想启动一个进程,读取它的 stdout 和 stderr(分开!),回显它并在进程终止时返回流的完整内容。

为了获得该功能,我使用了两个线程,每个线程都在读取不同的流 (stdout|stderr)。现在我遇到的问题是当 fgets 被第二次调用时 php 崩溃了。 (错误代码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;
    }
}

【问题讨论】:

    标签: php windows multithreading pthreads proc-open


    【解决方案1】:

    我发现了问题:

    虽然我在所有线程终止后关闭流,但似乎需要关闭正在读取它的线程内的流。 所以我在run 函数中用fclose($this-&gt;pipe); 替换了$this-&gt;stop(); 调用,一切正常。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多