为什么不是所有线程都完成了? [英] Why not all threads are completed?
问题描述
我已经尝试过从Joe回答 https://stackoverflow.com/a/32187103/2229367 中获取示例它很好用,但是当我尝试编辑这段代码时:
I've tried example from this Joe answer https://stackoverflow.com/a/32187103/2229367 and it works great, but when i tried to edit this code a little:
$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"的计数不同. 文件已过时. 这个问题怎么办?
Count of "Hello world" differs from count of "Collecting". Docs are out of date. What about this problem?
推荐答案
Worker::collect
并非旨在使您获得结果.它是不确定的.
Worker::collect
is not intended to enable you to reap results; It is non-deterministic.
Worker::collect
仅用于 ,旨在对Worker
对象堆栈中引用的对象运行垃圾回收.
Worker::collect
is only intended to run garbage collection on objects referenced in the stack of Worker
objects.
如果打算在每个结果可用时对其进行处理,则代码可能看起来像这样:
If the intention is to process each result as it becomes available, the code might look something like this:
<?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
结果集,并且在它们可用时,我进行了适当的同步以在主要上下文中获取结果.
This is obviously not very tolerant of errors, but the main difference is that I use a shared Volatile
collection of results, and I synchronize properly to fetch results in the main context as they become available.
如果您要等待所有结果可用,并可能避免某些争用锁(您应始终尝试避免这样做),那么代码看起来会更简单,例如:
If you wanted to wait for all results to become available, and possibly avoid some contention for locks - which you should always try to avoid if you can - then the code would look simpler, something like:
<?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
接口已经在最新版本的pthreads中由Threaded
实现-这是您应该始终使用的接口...
Noteworthy that the Collectable
interface is already implemented by Threaded
in the most recent versions of pthreads - which is the one you should be using ... always ...
文档已过时,对此感到抱歉...一个人...
The docs are out of date, sorry about that ... one human ...
这篇关于为什么不是所有线程都完成了?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!