我试图让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
,从那里进程似乎挂起,它不会退出,也不会再进一步给出了输出。
这里出了什么问题以及为了让它发挥作用需要发生什么?
答案 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模块,将其禁用。