многопоточность — использование многопоточного объекта в качестве многомерного ассоциативного массива PHP Pthreads

Моя проблема

Я пытаюсь разделить многомерный ассоциативный массив между различными потоками в CLI-приложении на основе pthreads. Проблема, с которой я сталкиваюсь, заключается в назначении ключей и значений без перезаписи предыдущих ключей.

Простой пример

Я создал простой пример, который, я надеюсь, отражает то, что я пытаюсь достичь в моем реальном коде.

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) или игнорирует дубликаты, а не объединяет вложенные массивы с одинаковыми ключами вместе.

Мой вопрос

Как установить и получить ключи и значения в нескольких измерениях при расширении потока?

Я использую PHP версии 7.04 и Pthreads версии 3.1.6.

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»).

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]