【问题标题】:Using Threaded Object as Multidimensional Associative Array PHP Pthreads使用线程对象作为多维关联数组 PHP Pthreads
【发布时间】:2016-04-07 19:04:52
【问题描述】:

我的问题

我正在尝试在基于 pthreads 的 CLI 应用程序中的不同线程之间共享一个多维关联数组。我遇到的问题是在不覆盖以前的键的情况下分配键和值。

简单示例

我创建了一个简单的示例,希望能反映我在真实代码中想要实现的目标。

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

我希望它的输出是 foo 和 bar 数组都有 20 个键和值,范围从 1 到 20。

然而,这个的实际输出是:

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

鉴于https://github.com/krakjoe/pthreads/blob/master/examples/StackableArray.php 中所写的内容,这对我来说有些意义,即“pthreads 使用我们自己的处理程序覆盖维度读取/写入器。我们的内部处理程序未设置为执行 ArrayAccess 接口。”

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

我的问题

扩展Threaded时如何设置和获取多维度的key和value?

我使用的是 PHP 7.04 版和 Pthreads 3.1.6 版。

【问题讨论】:

    标签: php multithreading pthreads php-pthread


    【解决方案1】:

    最终,我们找到了答案。 (感谢https://github.com/krakjoe/pthreads/blob/master/examples/StackableArray.php 中的评论,其中说“本身就是数组的数组成员也应该是 Threaded 的派生,尽管这不是绝对必要的”)。如果我们需要多维数组,我们需要编写方法来创建线程对象的新实例以充当数组,而不是尝试使用 [] 运算符设置键和值。

    例如,如果您需要一个带有嵌套数组的简单线程安全日志,它可能看起来像这样:

    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() {}
    
    }
    

    用法可能如下所示:

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

    这应该可以使用 [] 运算符完全像数组一样可读和可写,只要您不需要添加进一步的嵌套级别(在这种情况下,您需要添加“addSecondKey”方法) .

    【讨论】:

    • 这非常有帮助。处理 Theaded 对象中的多维数组是一场噩梦。感谢您的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多