使用线程对象作为多维关联数组 PHP Pthreads
Using Threaded Object as Multidimensional Associative Array PHP Pthreads
我的问题
我正在尝试在基于 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 overrides the dimension read/writers with our own handlers. Our internal handlers are not setup to execute ArrayAccess interfaces."
当我尝试使用 Threaded::merge 时,它会覆盖键(如果第二个参数设置为 true)或忽略重复项,而不是将具有相同键的嵌套数组连接在一起。
我的问题
如何在扩展 Threaded 时设置和获取多个维度的键和值?
我正在使用 PHP 版本 7.04 和 Pthreads 版本 3.1.6。
最终,我们找到了这个问题的答案。 (感谢 https://github.com/krakjoe/pthreads/blob/master/examples/StackableArray.php 中的评论 "Members of arrays that are themselves an array should also be a derivative of Threaded, though it's not strictly necessary")。如果我们需要多维数组,我们需要编写方法来创建线程对象的新实例以充当数组,而不是尝试使用 [] 运算符设置键和值。
例如,如果您需要一个带有嵌套数组的简单线程安全日志,它可能看起来像这样:
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" 方法)。
我的问题
我正在尝试在基于 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 overrides the dimension read/writers with our own handlers. Our internal handlers are not setup to execute ArrayAccess interfaces."
当我尝试使用 Threaded::merge 时,它会覆盖键(如果第二个参数设置为 true)或忽略重复项,而不是将具有相同键的嵌套数组连接在一起。
我的问题
如何在扩展 Threaded 时设置和获取多个维度的键和值?
我正在使用 PHP 版本 7.04 和 Pthreads 版本 3.1.6。
最终,我们找到了这个问题的答案。 (感谢 https://github.com/krakjoe/pthreads/blob/master/examples/StackableArray.php 中的评论 "Members of arrays that are themselves an array should also be a derivative of Threaded, though it's not strictly necessary")。如果我们需要多维数组,我们需要编写方法来创建线程对象的新实例以充当数组,而不是尝试使用 [] 运算符设置键和值。
例如,如果您需要一个带有嵌套数组的简单线程安全日志,它可能看起来像这样:
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" 方法)。