作者热门文章
- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我试过这个 Joe 回答中的例子 https://stackoverflow.com/a/32187103/2229367效果很好,但是当我尝试稍微编辑一下这段代码时:
$pool = new Pool(4);
while (@$i++<10) {
$pool->submit(new class($i) extends Collectable {
public function __construct($id) {
$this->id = $id;
}
public function run() {
printf(
"Hello World from %d\n", $this->id);
$this->html = file_get_contents('http://google.fr?q=' . $this->query);
$this->setGarbage();
}
public $id;
public $html;
});
}
while ($pool->collect(function(Collectable $work){
printf(
"Collecting %d\n", $work->id);
var_dump($work->html);
return $work->isGarbage();
})) continue;
$pool->shutdown();
“Hello world”的计数与“Collecting”的计数不同。文档已过时。这个问题怎么办?
最佳答案
Worker::collect
并不是为了让您收获结果;它是不确定的。
Worker::collect
仅旨在对 Worker
对象堆栈中引用的对象运行垃圾回收。
如果目的是在每个结果可用时对其进行处理,则代码可能如下所示:
<?php
$pool = new Pool(4);
$results = new Volatile();
$expected = 10;
$found = 0;
while (@$i++ < $expected) {
$pool->submit(new class($i, $results) extends Threaded {
public function __construct($id, Volatile $results) {
$this->id = $id;
$this->results = $results;
}
public function run() {
$result = file_get_contents('http://google.fr?q=' . $this->id);
$this->results->synchronized(function($results, $result){
$results[$this->id] = $result;
$results->notify();
}, $this->results, $result);
}
private $id;
private $results;
});
}
do {
$next = $results->synchronized(function() use(&$found, $results) {
while (!count($results)) {
$results->wait();
}
$found++;
return $results->shift();
});
var_dump($next);
} while ($found < $expected);
while ($pool->collect()) continue;
$pool->shutdown();
?>
这显然不能很好地容忍错误,但主要区别在于我使用共享的 Volatile
结果集合,并且我在主上下文中正确同步以在结果可用时在主上下文中获取结果。
如果您想等待所有结果可用,并可能避免一些锁争用(如果可以的话,您应该始终尽量避免),那么代码看起来会更简单,类似于:
<?php
$pool = new Pool(4);
$results = new Volatile();
$expected = 10;
while (@$i++ < $expected) {
$pool->submit(new class($i, $results) extends Threaded {
public function __construct($id, Volatile $results) {
$this->id = $id;
$this->results = $results;
}
public function run() {
$result = file_get_contents('http://google.fr?q=' . $this->id);
$this->results->synchronized(function($results, $result){
$results[$this->id] = $result;
$results->notify();
}, $this->results, $result);
}
private $id;
private $results;
});
}
$results->synchronized(function() use($expected, $results) {
while (count($results) != $expected) {
$results->wait();
}
});
var_dump(count($results));
while ($pool->collect()) continue;
$pool->shutdown();
?>
值得注意的是,Collectable
接口(interface)已经在最新版本的 pthreads 中由 Threaded
实现了——这是你应该使用的……总是……
文档已过时,对此感到抱歉......一个人......
关于php - 为什么不是所有线程都完成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34857779/
我是一名优秀的程序员,十分优秀!