1

My Problem

I am trying to share a multi-dimensional associative array between different threads in a pthreads - based CLI application. The problem I am encountering is with assigning keys and values without overwriting previous keys.

Simple Example

I've created a simple example which I hope reflects what I am trying to achieve in my real code.

class MyWork extends Worker {

    public function __construct($log) {
        $this->log = $log;
    }

    public function getLog() {
        return $this->log->getLog();
    }

    public function run() {}

    }

class Log extends Threaded {
    private $log;

    public function __construct() {
        $this->log = new class extends Threaded {
            public function run() {}
        };
    }

    public function run(){}

    public function report() {
        print_r($this->log['foo'].PHP_EOL);
        print_r($this->log['bar'].PHP_EOL);
    }

    public function getLog() { return $this->log; }
}

class MyTask extends Threaded {

    private $complete=false;
    private $i;

    public function isComplete() {
        return $this->complete;
    }

    public function run() {
        $this->worker->getLog()['bar'][$this->i] = $this->i;
        $this->worker->getLog()['foo'][$this->i] = $this->i;
        $this->complete= true;


        }

    public function __construct($i) {
            $this->i = $i;
        }
    }

$log = new Log();

$p = new Pool(4, MyWork::class, [$log]);

foreach(range(0, 20) as $i)
    $p->submit(new MyTask($i));


$log->report();

What I'd like the output of this to be is that the foo and bar arrays both have 20 keys and values ranging from 1 to 20.

However, the actual output of this is:

PHP Notice:  Indirect modification of overloaded element of     class@anonymous has no effect in /home/fraser/Code/AlignDb/src/test.php on     line 50

Which somewhat makes sense to me given what's written in https://github.com/krakjoe/pthreads/blob/master/examples/StackableArray.php, namely that "pthreads overrides the dimension read/writers with our own handlers. Our internal handlers are not setup to execute ArrayAccess interfaces."

When I try to use Threaded::merge it overwrites the keys (if the second argument is set to true) or ignores duplicates rather than concatenating nested arrays with the same keys together.

My Question

How do I set and get keys and values in multiple dimensions when extending Threaded?

I'm using PHP version 7.04 and Pthreads version 3.1.6.

1 Answer 1

1

Eventually, we figured out the answer to this. (Thanks to a remark in https://github.com/krakjoe/pthreads/blob/master/examples/StackableArray.php, where it says "Members of arrays that are themselves an array should also be a derivative of Threaded, though it's not strictly necessary"). Instead of trying to set keys and values with the [] operator we needed to write methods to create new instances of threaded objects to act as arrays if we needed multidimensional arrays.

For example, if you needed a simple threadsafe log with nested arrays it might look something like this:

class BaseLog extends Threaded {

    public function run() {}

    public function addBaseKey($key) {

        $this[$key] = new SafeArray();
    }

    public function addFirstKey($base, $key) {
         $this[$base][$key] = new SafeArray();
    }

 }

class SafeArray extends Threaded {

     public function run() {}

}

Usage might look something like this:

$log = new BaseLog();

$log->addBaseKey("foo");
$log->addFirstKey("bar");
$log["foo"]["bar"]["my"] = "value";

This should then be readable and writeable using the [] operator exactly like an array as long as you don't need to add a further level of nesting (in which case you'd need to add an "addSecondKey" method).

Sign up to request clarification or add additional context in comments.

1 Comment

This was extremely helpful. Dealing with multidimensional arrays in Theaded objects was a nightmare. Thank you for the solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.