为什么不是所有线程都完成了? [英] Why not all threads are completed?

查看:91
本文介绍了为什么不是所有线程都完成了?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经尝试过从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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆