0

I am trying to learn multithreading with PHP. I've installed PHP 7.2.14 with ZTS support, and looked over a lot of examples on the net, and afterwards, tried to create a simple script, to see if I understand the things that I've learned. The problem is, that it seems, I don't:)

Here's the script I've made:

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;

This script, should create 15 separate tasks, and in each task I would have to iterate a 100 times. After each 100 iterations are ready, I would like to store the number of times I've iterated in the MyDataHolder class, to be able to access it later.

The expected behaviour would be, that when I run this script, I would like to see 100 printed out 15 times on the screen, and in the end, I would like to see Total: 1500 printed out.

Instead of this, 100 is printed out 15 times, but the total value remains empty at the end.

What am I doing wrong? How can I collect the data from each of my threads, to use it later on in the program?

Adam Baranyai
  • 3,635
  • 3
  • 29
  • 68
  • Does [this question and answer](https://stackoverflow.com/questions/70855/how-can-one-use-multi-threading-in-php-applications) help? – Dave Jan 16 '19 at 14:02

1 Answers1

0

Let me give you similar examples,

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

?>

This example I tried to modify from examples in github. Sorry I don't fully understand the flow about Threaded objects, and class Thread. Figure yourself about work flow by your own perspective.