1

私の問題

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に書かれていることを考えると、これはある程度理にかなっています。 ArrayAccess インターフェイスを実行するように設定されていません。」

Threaded::merge を使用しようとすると、同じキーを持つネストされた配列を連結するのではなく、キーを上書きするか (2 番目の引数が true に設定されている場合)、重複を無視します。

私の質問

Threaded を拡張するときに、複数の次元でキーと値を設定および取得するにはどうすればよいですか?

PHP バージョン 7.04 と Pthreads バージョン 3.1.6 を使用しています。

4

1 に答える 1

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」メソッドを追加する必要があります)。

于 2016-04-07T11:04:52.450 に答える