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

时间:2016-04-06 15:51:06

标签: php multithreading pthreads php-pthread

我的问题

我正在尝试在基于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时设置和获取多个维度的键和值?

我正在使用PHP版本7.04和Pthreads版本3.1.6。

1 个答案:

答案 0 :(得分:0)

最终,我们找到了答案。 (感谢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”方法),这应该使用[]运算符可读和可写,就像数组一样