Worker :: collect不是为了让您获得成果;这是不确定的.
Worker :: collect仅用于对Worker对象堆栈中引用的对象运行垃圾回收.
如果打算在每个结果可用时处理它们,那么代码可能如下所示:
$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结果集合,并且我可以正确地同步以在主环境中获取结果.
如果你想等待所有结果变得可用,并且可能避免一些争用锁 – 如果可以的话你应该总是试图避免 – 那么代码看起来会更简单,例如:
$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();
?>
值得注意的是,在最新版本的pthreads中,Threaded已经实现了Collectable接口 – 这是你应该使用的…总是……
文档已经过时了,对不起……一个人……