Многопоточность PHP - Как я могу получить результаты из всех потоков, когда они будут готовы?

Я пытаюсь научиться многопоточности с помощью 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 раз, но общее значение остается пустым в конце.

Что я делаю неправильно? Как я могу собрать данные из каждого из моих потоков, чтобы использовать их позже в программе?

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 Stackru post for additional information:
                https://stackru.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. Извините, я не до конца понимаю поток потоковых объектов и класса Thread. Подумайте о рабочем процессе с вашей точки зрения.

Другие вопросы по тегам