pthreads挂起/卡在池上 - >提交

时间:2016-12-16 16:27:17

标签: php pthreads php-7

我试图让Pthreads工作,但不幸的是,对于所有过时的文档,很难弄清楚当前和发生了什么变化。以及没有收到任何错误。

使用最新版本的pthreads和xDebug

运行PHP7.2.0-dev

目前我有

<?php

$THREADS = 3;

class UptimeWorker extends Worker {
    public function start(?int $options = null) {
        return parent::start(PTHREADS_INHERIT_CLASSES | PTHREADS_INHERIT_CONSTANTS | PTHREADS_INHERIT_FUNCTIONS);
    }
}

class UptimeWork extends Threaded {

    private $i;

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

    public function run() {
        echo "I am ".$i.PHP_EOL;
        $this->setGarbage();
    }

}

$pool = new Pool($THREADS, UptimeWorker::class);

for($i=0;$i<10;$i++) {
    var_dump($i);
    $pool->submit(new UptimeWork($i));
}

echo "pre-shutdown".PHP_EOL;

$pool->shutdown();

echo "finished".PHP_EOL;

并且唯一的输出是来自int(0)语句中第一个var_dump调用的for,从那里进程似乎挂起,它不会退出,也不会再进一步给出了输出。

这里出了什么问题以及为了让它发挥作用需要发生什么?

2 个答案:

答案 0 :(得分:3)

我的代码中有两个错误,都在

 public function run() {
    echo "I am ".$i.PHP_EOL;
    $this->setGarbage();
}

首先它应该是$this->i(简单的拼写错误)

其次是找不到setGarbage,因为它是Collectable的属性(http://php.net/manual/en/collectable.setgarbage.php - 注意:手册记录了旧的PHP 5 / API版本2类,这个已更改为PHP 7 / API版本3的界面。因此你需要

class UptimeWork extends Threaded  Implements Collectable {

访问setGarbage()。由于Collectable是一个接口,您还需要编写接口方法。

这是您的工作代码:

$THREADS = 3;

class UptimeWorker extends Worker {
    public function start(?int $options = null) {
        return parent::start(PTHREADS_INHERIT_CLASSES | PTHREADS_INHERIT_CONSTANTS | PTHREADS_INHERIT_FUNCTIONS);
    }
}


class UptimeWork extends Threaded  Implements Collectable {

    private $i;
    private $isGarbage = false;

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

    public function run() {
        echo "I am ".$this->i.PHP_EOL;
        $this->setGarbage();
    }

    public function setGarbage() {
        echo "Setting garbage ".$this->i.PHP_EOL;
        $this->isGarbage = true;
    }

    public function isGarbage() : bool {
        return $this->isGarbage;
    }

}

$pool = new Pool($THREADS, UptimeWorker::class);

for($i=0;$i<10;$i++) {
    var_dump($i);
    $pool->submit(new UptimeWork($i));
}

echo "pre-shutdown".PHP_EOL;

$pool->shutdown();

echo "finished".PHP_EOL;

答案 1 :(得分:0)

这里要添加另一个注释:

事实证明,启用 blackfire模块后,它会再次“挂起”而不会返回任何错误,而禁用blackfire模块实际上会按预期返回输出/错误。

对于那些遇到同样奇怪问题的人来说,如果您安装了blackfire模块,将其禁用