0

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

这是我制作的脚本:

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 次,但最后的总值仍然为空。

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

4

1 回答 1

0

让我给你类似的例子,

<?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);

?>

这个示例我尝试从github 中的示例进行修改。抱歉,我不完全了解线程对象和线程类的流程。从你自己的角度来思考工作流程。

于 2019-03-21T03:59:11.893 回答