简体   繁体   English

使用线程对象作为多维关联数组 PHP Pthreads

[英]Using Threaded Object as Multidimensional Associative Array PHP Pthreads

My Problem我的问题

I am trying to share a multi-dimensional associative array between different threads in a pthreads - based CLI application.我正在尝试在基于 pthreads 的 CLI 应用程序中的不同线程之间共享多维关联数组。 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.我希望它的输出是 foo 和 bar 数组都有 20 个键和从 1 到 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."考虑到https://github.com/krakjoe/pthreads/blob/master/examples/StackableArray.php 中写的内容,这对我来说有些道理,即“pthreads 用我们自己的处理程序覆盖了维度读/写者。我们的内部处理程序未设置为执行 ArrayAccess 接口。”

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.当我尝试使用 Threaded::merge 时,它​​会覆盖键(如果第二个参数设置为 true)或忽略重复项,而不是将具有相同键的嵌套数组连接在一起。

My Question我的问题

How do I set and get keys and values in multiple dimensions when extending Threaded?扩展Threaded时如何设置和获取多个维度的键和值?

I'm using PHP version 7.04 and Pthreads version 3.1.6.我使用的是 PHP 7.04 版和 Pthreads 3.1.6 版。

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"). (感谢https://github.com/krakjoe/pthreads/blob/master/examples/StackableArray.php 中的评论,其中说“本身是数组的数组成员也应该是 Threaded 的衍生物,尽管它是不是绝对必要的”)。 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).只要您不需要添加更多级别的嵌套(在这种情况下,您需要添加一个“addSecondKey”方法),这应该是可读和可写的,就像数组一样使用 [] 运算符。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM