2013-02-10 49 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 2013-02-10 10:16:49

+0

@ user2058508:我試圖在我的php中無法使用pthreads。但無法做到這一點。你能告訴我該怎麼做。 – Cindrella 2013-03-26 10:59:50

回答

31

的問題

PHP是一個共享環境:這意味着,每個進程(或線程)都必須有它的解釋的自己的副本,所有的模塊和用戶碼。

HashTable不僅支持PHP數組,而且在整個PHP代碼庫中使用的結構從未打算被多個上下文操縱。內存管理器,每當你設置一個數組的新成員(等價於malloc),取消設置(相當於free),或者更新一個(相當於free和malloc)時,內存管理器就會被調用,這是一個不可或缺的組成部分無共享體系結構,並且除其他外特別設計爲禁止任何上下文來釋放由另一個上下文分配的內存,因爲這構成了對共享任何內容的違反。

虛擬機假定它是操作數組的唯一上下文。

所有擴展代碼都做出相同的假設。

忽略規則的後果 - 什麼都不分享 - 是非常可怕的:你崩潰了PHP。

所有這些使得您可以在多個上下文中存儲和操作實際的數組,並且不應該讓它變得不可取。

PHP5

陣列將在設置它們作爲Threaded對象的成員進行序列化。

您應該用Threaded對象替換您的陣列用法。

A 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

並行線程V3(PHP7)引入了自動不變性的理念,爲Threaded對象。

從我blog交上不變性引用在並行線程V3:

在並行線程v3中,一個Threaded對象的成員()設置到另一Threaded對象()使得參考該A成立至B不可變。

不變性是性能優化。

顯然,數組的大多數用例涉及到對數組進行變異,而這些對象現在不能總是支持。

在這種特殊情況下,Threaded陣列的成員都不是Threaded

pthreads v3(PHP7)引入了Volatile對象的概念。

揮發性形容詞:承擔責任的快速和變幻莫測,特別是對惡化。

Volatile對象比慢Threaded對象,因爲它們不能從不變性允許我們做出的性能優化中受益。

Volatile對象確實是pthreads v3中數組的良好選擇。並行線程會迫使陣列時,他們被設置爲Threaded對象的成員Volatile對象:

<?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(); 
?> 

將產生:

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

這將導致$this->array表現的Thread運行期間預期。

有一個副作用,通過下面的代碼的輸出示出:

<?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" 
} 

注意,Volatile對象在Threadarray斷開連接的被提供給它的構造函數,所以主要的上下文仍然在操作array

Thread處理從另一個源傳入的數組時,自動強制用於降低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 2013-02-11 01:11:06

+2

如何使用數組函數(例如:arrap_pop)$ this-> storage – user2058508 2013-02-11 01:31:26

+1

您可以像數組一樣操作它,但它不是_an_數組。如果你需要該對象具有功能,那麼你需要以不同的方式進行編程,而不是[]你可能有一個push(),允許你存儲索引和編程一個pop() – 2013-02-11 07:55:59