gpt4 book ai didi

php - 为什么不是所有线程都完成?

转载 作者:可可西里 更新时间:2023-10-31 23:02:47 24 4
gpt4 key购买 nike

我试过这个 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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com