【问题标题】:PHP Multi Threading - How can I obtain the results from all the threads when they are ready?PHP 多线程 - 当所有线程准备就绪时,如何从它们获取结果?
【发布时间】:2019-01-15 12:19:48
【问题描述】:

我正在尝试使用 PHP 学习多线程。我已经安装了支持ZTS的PHP 7.2.14,并在网上查看了很多示例,然后尝试创建一个简单的脚本,看看我是否理解我所学到的东西。问题是,看来,我没有:)

这是我制作的脚本:

class Task extends Threaded
{
    private $workToBeDone;

    public $DataHolder;

    public function __construct($i, $z, $DataHolder)
    {
        $this->workToBeDone = array($i, $z);
        $this->DataHolder = $DataHolder;
    }

    public function run()
    {
        $results = 0;

        for ($i=$this->workToBeDone[0]; $i<=$this->workToBeDone[1]; $i++) {
            $results++;
        }

        $this->synchronized(function ($DataHolder) use($results) {
            echo $results . "\n";
            $DataHolder->counter+=$results;
        }, $this->DataHolder);
    }
}

class MyDataHolder {
    public $counter;
}

$DataHolder = new MyDataHolder;
$pool = new Pool(4);
$tasks = array();
for ($i = 0; $i < 15; ++$i) {
    $Task = new Task(1,100, $DataHolder);
    $pool->submit($Task);
}

while ($pool->collect());
$pool->shutdown();

echo "Total: " . $DataHolder->counter;

这个脚本应该创建 15 个单独的任务,并且在每个任务中我必须迭代 100 次。在每 100 次迭代准备就绪后,我想将我迭代的次数存储在 MyDataHolder 类中,以便以后能够访问它。

预期的行为是,当我运行此脚本时,我希望看到 100 在屏幕上打印 15 次,最后,我希望看到 Total: 1500 打印出来。

与此不同,100 被打印了 15 次,但最后的总值仍然为空。

我做错了什么?如何从我的每个线程中收集数据,以便稍后在程序中使用?

【问题讨论】:

标签: php multithreading php-pthread


【解决方案1】:

让我给你类似的例子,

<?php
/*
Threaded objects (which subsequently includes Volatile objects) are tied to the
context in which they are created. They can be used to fetch data from a thread,
but must be created in the outer most thread in which they are used.
*/
// create Threaded object in the main thread

class DataHolder extends Threaded{
        public $counter;
        public function __construct(){
                $this->counter = 0;
        }
}

class threading extends Thread {
        public $store;
        public $workdone;
        public function __construct(Threaded $store, $i, $z)
        {
                $this->store = $store;
                $this->workdone = array($i, $z);
        }
        public function run()
        {
                /*
                The following array cast is necessary to prevent implicit coerci
on to a
                Volatile object. Without it, accessing $store in the main thread
 after
                this thread has been destroyed would lead to RuntimeException of
:
                "pthreads detected an attempt to connect to an object which has
already
                been destroyed in %s:%d"
                See this StackOverflow post for additional information:
                https://stackoverflow.com/a/44852650/4530326
                */
                $rescount = 0;
                for($i = $this->workdone[0]; $i <= $this->workdone[1]; $i++){
                        $rescount++;
                }
                $this->store['counter'] += $rescount;

        }
}

$store = new DataHolder();
$pool = new Pool(3);
for($i = 0; $i < 15; $i++){
        $task = new threading($store, 1, 100);
        $pool->submit($task);
}

$pool->shutdown();

print_r($store);

?>

这个例子我尝试从examples in github修改。 抱歉,我不完全了解线程对象和线程类的流程。从你自己的角度了解工作流程。

【讨论】:

    猜你喜欢
    • 2011-03-11
    • 2017-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多