2015-11-04 29 views
0

我對PHP相當陌生,現在對pthreads來說很新。php pthreads和使用一個類來存儲線程之間共享的數據

我使用的是最新的PHP7 RC6身材,從混帳/ src目錄內置並行線程,以獲得最新的(並試圖「官方」 v3.0.8一個),在Ubuntu 3.13.0-66泛型

我正在嘗試編寫一個線程化的解決方案來讀取套接字中的數據並對其進行處理。我使用線程來嘗試最大限度地提高性能,這主要是因爲我正在執行諸如http請求(針對AWS DynamoDB和其他服務)等操作,並且正在等待來自外部系統的響應,因此我可以從中受益穿線。

我的真實代碼比這更復雜。這是顯示我的問題的簡單示例。

我想要做的是'緩存'從數據庫(AWS DynamoDB)獲得的'數組'中的某些信息,以便獲得更好的性能。我需要每個線程都能夠使用/訪問並修改這個「全局」緩存,並在緩存中使用多個「記錄」。

我在測試中取得了巨大的成功,並以這種方式簡單地存儲了一個字符串,但是現在我要做的是真實的,我需要存儲更復雜的數據,並且我決定使用一個小類(cacheRecord)記錄,而不是一串簡單的數據。但問題是,當我嘗試將值賦給類成員時,它似乎不想'保存',返回到數組。

我設法通過將整個'class'複製到一個tmp變量,修改它,然後將整個類保存回數組,但這似乎是代碼開銷,並且我會需要將其包裝在 - > synchronized中以保持線程之間的完整性。

這是唯一正確地做到這一點的方法,將其複製到tmp並將其複製回來並使用'synchronized',或者我正在做其他錯誤/愚蠢的事情嗎?

試驗它,我做了cacheRecord類'extends Threaded'。這使得成員的單一分配工作正常,但是這使得它不可變,並且以後我無法在緩存中取消/刪除該記錄。

代碼來說明我的意思:

<?php 

class cacheRecord { 
    public $currentPos; 
    public $currentRoom; 
    public $someOtherData; 
} 

class cache extends Threaded { 
    public function run() {} 
} 

class socketThread extends Thread { 

    public function __construct($myCache) { 
     $this->cacheData = $myCache; 
    } 

    public function run() { 

     // This will be in a loop, waiting for sockets, and then responding to them, indefinitely. 

     // At some point, add a record to the cache 
     $c = new cacheRecord; 
     $c->currentPos = '1,2,4'; 
     $c->currentRoom = '2'; 
     $this->cacheData['record1'] = $c; 

     var_dump($this); 

     // Later on, update the cache record, but this doesnt work 
     $this->cacheData['record1']->currentRoom = '3'; 

     var_dump($this); 

     // However this does work, but is this the correct way? Seems like more code to execute, than a simple assign, and obviously, I would need to use synchronized to keep integrity, which would further slow it down. 

     $tmp = $this->cacheData['record1']; 
     $tmp->currentRoom = '3'; 
     $this->cacheData['record1'] = $tmp; 

     var_dump($this); 

     // Later on some more, remove the record 
     unset($this->cacheData['record1']); 

     var_dump($this); 

     // Also will be using ->synchronized to enforce integrity of certain other operations 
     // Just an example of how I might use it 

/* 
     $this->cacheData->synchronized(function() { 
      if ($this->cacheData['record1']->currentRoom == '3') { 
       $this->cacheData['record1']->Pos = '0,0,0'; // Obviously this wont work as above. 
       $this->cacheData['record1']->currentRoom = '4'; 
      } 
     }); 
*/ 
    } 
} 

// Main 

$myCache = new cache; 

for ($th=0;$th<1;$th++) { // Just 1 thread for testing 
    $socketThreads[$th] = new socketThread($myCache); 
    $socketThreads[$th]->start(); 
} 

回答

1

延伸\螺紋是要走的路。 但是,緩存中的「任何內容」都應該從中進行擴展,而不僅僅是緩存itsef。

它在手冊的某處(對不起,不記得確切的地方),只有易變的(又名線程)對象不會是我不可改變的。

因此,如果你的類cacheRecord沒有從線程擴展,它將是不可變的,甚至到另一個線程結構。

線程使內部屬性數組自動變爲volatile(因此線程可用),但如果它們沒有從線程擴展,則不是對象。

嘗試從線程擴展cacheRecord並告訴我它是否可用。

  • 菲爾+
+0

我以前試過了。使它成爲Threaded確實可以「修復」它來改變成員位。但是,沒有人會抱怨對象是不可改變的,不會讓我這樣做,所以我沒有辦法去除'記錄'(我可以弄清楚)。 –

+0

將CacheRecords作爲易失性對象進行分配也意味着,只要原始線程超出範圍,它們就會被破壞,據我所知。所以你不希望Record是從Threaded中派生出來的,你也不希望它是揮發性的。將它類型化爲其他對象類型或數組似乎對我來說是正確的。 – Gralgrathor

相關問題