2013-02-10 20 views
12

私はPECL pthreadを見つけましたThreadは配列オブジェクトを使用できません。原因を見つけるために私は何ができますか?PHP/pthreadsスレッドクラスは配列を使用できませんか?

コード例:

class my extends Thread { 

      public function __construct() { 
        $this->arr = array(); 
        $this->id = 0; 
      } 
      pulbic function run() { 
        while (true) { 
          $this->wait(); 
        } 
      } 

      public function set() { 
        $this->id = rand(0, 1000); 
        $this->arr[] = rand(0, 1000); 
        var_dump($this->id);//this is rand 
        var_dump($this->arr);//this is empty array() 
        $this->notify(); 
      } 
    } 

    $my = new my(); 
    $my->start(); 
    while (true) { 
      sleep(1); 
      $my->add(); 
    } 
+1

'add()'メソッドはありません:? – KingCrunch

+0

@ user2058508:私は自分のPHPでpthreadsをできないようにしようとしています。しかし、それを行うことはできません。どうすればいいか教えてください。 – Cindrella

答えて

31

問題

PHPは、シェアード・ナッシング環境である:これは、各プロセス(またはスレッド)は、それが自身のインタプリタのコピー、すべてのモジュール、およびユーザーの持っている必要があることを意味しコード。

HashTable PHP配列をサポートするだけでなく、PHPコードベース全体で使用される構造は、複数のコンテキストによって操作されることはありませんでした。

メモリマネージャは、配列の新しいメンバ(mallocに相当)を設定し、unset(空き)、またはupdate(mallocと同じ)を呼び出すときに呼び出されます。共有されていないアーキテクチャの中にあり、特に、共有されていないものの違反を構成するため、別のコンテキストによって割り当てられたメモリをフリーズすることをコンテキストが禁止するように特に設計されています。

仮想マシンは、それがアレイを操作する唯一のコンテキストであることを前提としています。

すべての拡張コードは同じ前提です。

ルールを無視した場合の影響 - 何も共有しない - は悲惨です:PHPがクラッシュします。

これにより、実際の配列を複数のコンテキストで格納および操作することが不可能になり、何か望ましくないものにする必要があります。

PHP5

アレイはThreadedオブジェクトのメンバーとして、それらを設定する際にシリアル化されるであろう。

アレイの使用をThreadedオブジェクトに置き換える必要があります。

Threadedオブジェクトはのように操作することができます。は配列です。ここで

はあなたが始めるために何かである:

<?php 
class Test extends Thread { 
    public function __construct(Threaded $storage) { 
     $this->storage = $storage; 
    } 

    public function run(){ 
     $i = 0; 
     while(++$i < 10) { 
      $this->storage[]=rand(0,1000); 
     } 

     $this->synchronized(function($thread){ 
      $thread->stored = true; 
      $thread->notify(); 
     }, $this); 
    } 
} 

$storage = new Threaded(); 
$my = new Test($storage); 
$my->start(); 

$my->synchronized(function(Thread $thread){ 
    while (!$thread->stored) { 
     $thread->wait(); 
    } 
}, $my); 

var_dump($storage); 
?> 

PHP7

pthreadsのv3の(PHP7)Threadedオブジェクトの自動不変性の概念を紹介します。 pthreadのv3では不変の私blogポストから

引用:別のThreadedオブジェクトへThreadedオブジェクトのメンバー()を設定pthreadのv3では

、(B)を参照することは、Bに不変です。

不変性はパフォーマンスの最適化です。

明らかに、配列の大部分のユースケースでは、アレイを突然変異させることがあります。Threadedオブジェクトは、常にサポートできない場合があります。

この特定のケースでは、ThreadedアレイのメンバーのいずれもThreadedではありません。

pthreads v3(PHP7)は、Volatileという概念を導入しています。揮発性

、形容詞:特に悪い方のために、迅速かつ予測不能に変化しやすいです。彼らは私たちが行うことができ不変パフォーマンスの最適化の恩恵を受けることができないため

VolatileオブジェクトがThreadedオブジェクトよりも遅いです。

Volatileオブジェクトは、pthreads v3の配列の代わりになります。

<?php 
class Test extends Thread { 
    public function run(){ 
     $array = [ 
      "Hello", 
      "World" 
     ]; 

     var_dump($array); 

     $this->array = $array; 

     var_dump($this->array); 
    } 
} 

$test = new Test(); 
$test->start() && $test->join(); 
?> 

が得られます:pthreadsのは、それらがThreadedオブジェクトのメンバーとして設定されているVolatileオブジェクトに配列を強制変換します

array(2) { 
    [0]=> 
    string(5) "Hello" 
    [1]=> 
    string(5) "World" 
} 
object(Volatile)#2 (2) { 
    [0]=> 
    string(5) "Hello" 
    [1]=> 
    string(5) "World" 
} 

これはThreadの実行時に期待どおりに動作する$this->arrayの原因となります。

副作用は、次のコードの出力によって示される、あり:

<?php 
class Test extends Thread { 
    public function __construct(array $array) { 
     $this->array = $array; 
    } 

    public function run(){ 
     var_dump($this->array); 
    } 
} 

$array = [ 
    "Hello", 
    "World" 
]; 
$test = new Test($array); 
$test->start() && $test->join(); 
var_dump($array); 
?> 

をもたらす:

object(Volatile)#2 (2) { 
    [0]=> 
    string(5) "Hello" 
    [1]=> 
    string(5) "World" 
} 
array(2) { 
    [0]=> 
    string(5) "Hello" 
    [1]=> 
    string(5) "World" 
} 

ThreadVolatileオブジェクトがそのarrayから切断されていることに注意をそのコンストラクタに供給されたので、主なコンテキストはまだarrayを操作しています。

自動強制変換は、Threadが別のソースから渡された配列を操作するときに、1分あたりのwtfsを減らすのに役立ちます。

明示的に指定する方が良いです。強制に依存しないことが最善の選択肢です。

依存関係の中には配列があることが既に分かっている場合は、メンバーとして設定する前にそれを処理して、強制的に強制的に回避してください。

明示的なキャストを使用してVolatileへの自動強制を回避することが可能である:

<?php 
class Test extends Thread { 
    public function run() { 
     $this->result = (array) [ 
      "Hello" => "World" 
     ]; 
    } 
} 

$test = new Test(); 
$test->start() && $test->join(); 
var_dump($test->result); 
?> 

が、これはあなたが本当にしたいないときに便利ですコード例が示すように

array(1) { 
    ["Hello"]=> 
    string(5) "World" 
} 

得られます配列を使用して結果を格納するPHP5と同様に、配列は保存用にシリアル化されます。

+0

ありがとう、私は理解しています。 – user2058508

+2

$ this-> storageの配列関数(例:arrap_pop)の使い方 – user2058508

+1

配列と同じように操作できますが、_an_配列ではありません。オブジェクトを機能させる必要がある場合は、[]ではなくpush()を使用して、別の方法でプログラムする必要がある場合は、インデックスを保存してpop()をプログラムできます –

関連する問題