Pool :: collect如何运作?

时间:2015-02-09 18:35:41

标签: php callback pthreads threadpool

帮助我了解Pool :: collect的确切运作方式。

Pool :: collect - 收集对已完成任务的引用

public void Pool::collect ( Callable $collector )

我假设:Pool::collect注册一个函数,该函数将在每个\Threaded $task完成后调用。所以,我做了:

<?php
$pool = new Pool(4);
$pool->collect($collector);
$pool->submit(new Task);

没有工作。但以下是:

<?php
$pool = new Pool(4);
$pool->submit(new Task);
$pool->collect($collector);

所以,我猜Pool::collect的作用是:将$collector附加到之前提交的每个\Threaded $task

现在,当$collector被调用时?我假设在Threaded::run()完成后被调用。错了。

<?php
class Task extends Threaded {
    public function run () { echo "Task complete\n"; }
}

$collector = function (\Task $task) {
    echo "Collect task\n";
    return true;
};

$pool = new Pool(4);
$pool->submit(new Task);
$pool->collect($collector);
$pool->shutdown();

输出:

Collect task
Task complete
$collector完成之前调用

Threaded::run()


文档并没有多说。没有事件说$collector必须返回一个布尔值。 I didn't know that

我试图在每个$ task完成后使用Pool :: collect作为回调类型。我想我走错了路。

修改1. What about this attempt

1 个答案:

答案 0 :(得分:1)

您错过了审核周期。 任务无法立即完成,因此首先收集功能不会收到正面结果。需要多次检查,需要一个循环。

在示例中,如果无限为真,则总是有4个任务正常工作。否则,如果队列的大小与池大小(4)相等,则它结束,您可以退出循环。

<?php

class Task extends \Threaded
{

    protected $result;
    protected $completed = false;

    public function run()
    {
        echo "Task complete\n";
        $this->result = md5(rand(1, 2000));
        sleep(rand(1, 5));
        $this->completed = true;
    }

    public function isCompleted()
    {
        return $this->completed;
    }

    public function getResult()
    {
        return $this->result;
    }
}

$infinite = false;
$poolSize = 4;
$queue = array();

$pool = new \Pool($poolSize);
$pool->submit(new Task);
$pool->submit(new Task);
$pool->submit(new Task);
$pool->submit(new Task);


do {
    if($infinite === true){
        $queue = array();
    }

    $pool->collect(function (\Task $task) use (&$queue) {
        if ($task->isCompleted()) {
            echo "Collect task\n";
            $queue[] = $task->getResult();

            return true;
        } else {
            echo "task not complete\n";

            return false;
        }
    });

    $size = sizeof($queue);
    if ($size > 0) {

        echo $size . " result\n";
        print_r($queue);

        if($infinite === true) {
            for ($m = 0; $m < $size; $m++) {
                $pool->submit(new Task);
            }
        } else{
            if($size == $poolSize){
                break;
            }
        }
    }

    usleep(100000);

} while (true);
$pool->shutdown();