2012-01-03 56 views
2

我敢肯定,我正在嘗試的是非常簡單的,但我從來沒有用過多線程之前,所以我不知道從哪裏開始。在PHP中的子進程之間共享變量?

我使用PCNTL來創建一個多線程的PHP應用程序。我想要做的是有3個函數同時運行,我希望他們的返回值合併成一個單一的數組。因此在邏輯上,我需要一個變量共享他們追加結果的所有孩子之間共享的變量,或者三個變量只在一個孩子和父母之間共享 - 然後父母可以在稍後合併結果。

問題是 - 我不知道如何做到這一點。首先想到的是使用shared memory,但我覺得應該有一個更簡單的方法。

此外,如果它有任何作用,分叉進程的函數是公共類方法。所以,我的代碼看起來像下面這樣:

<?php 
    class multithreaded_search { 
     /* ... */ 
     /* Constructors and such */ 
     /* ... */ 
     public function search($string = '') { 
      $search_types = array('tag', 'substring', 'levenshtein'); 
      $pids = array(); 
      foreach($search_types as $type) { 
       $pid = pcntl_fork(); 
       $pids[$pid] = $type; 
       if($pid == 0) { // child process 
        /* confusion */ 
        $results = call_user_func('multithreaded_search::'.$type.'_search', $string); 
        /* What do we do with $results ? */ 
       } 
      } 
      for($i = 0; $i < count($pids); $i++) { 
       $pid = pcntl_wait(); 
       /* $pids[$pid] tells me the type of search that just finished */ 
       /* If we need to merge results in the parent, we can do it here */ 
      } 
      /* Now all children have exited, so the search is complete */ 
      return $results; 
     } 
     private function tag_search($string) { 
      /* perform one type of search */ 
      return $results; 
     } 
     private function substring_search($string) { 
      /* perform one type of search */ 
      return $results; 
     } 
     private function levenshtein_search($string) { 
      /* perform one type of search */ 
      return $results; 
     } 
    } 
?> 

這樣,我需要使用shmop_open我打電話pcntl_fork前創建共享內存並保存結果出現,還是孩子們分享類變量?還是他們只共享全局變量?我相信答案很簡單......我只是不知道。

回答

4

分叉的孩子一旦寫入任何地方就會獲得他們自己的內存空間的專用副本 - 這是「寫入時複製」。雖然shmop確實提供了對公共內存位置的訪問,但實際的PHP變量以及腳本中未定義的內容不會在子項之間共享。

做一個孩子的$x = 7;不會讓其他孩子中的$ x也變成7.每個孩子都有自己專用的$ x,它完全獨立於其他人的副本。

+0

這很有道理,但我該如何讓孩子在父母的範圍內編輯一個變量呢?我必須使用共享內存,還是有其他方法? – stevendesu 2012-01-03 02:59:58

+0

你不能。 PHP不提供必要的低級內存訪問,讓您找出父內存的位置並直接與它通信。即使您可以通過指針或其他方法訪問父進程的內存,也不能保證父進程的內存佈局與孩子的內存佈局保持一致。你必須處理php引擎的內部存儲器映射以找出變量的位置等等......使用共享內存,或者在兩個進程之間打開一個雙向通信通道,並構建一個小數組api來發回數據並且。 – 2012-01-03 12:41:00

+0

我已經使用共享內存現在寫了一個答案,但我喜歡雙向通信通道的想法(特別是因爲這不會限制返回值,而您必須以字節爲單位定義共享內存的大小) 。我該如何着手創建? – stevendesu 2012-01-03 15:44:24

0

只要父親和孩子知道共享內存段的鍵/鍵是可以在pcnlt_fork之前執行shmop_open的。但請記住,pcnlt_fork在子進程中返回0,在創建子進程失敗時返回-1(在評論/ 混淆 /附近檢查代碼)。父親將在$ pid中創建剛剛創建的子進程的PID。

檢查在這裏:

http://php.net/manual/es/function.pcntl-fork.php

+0

謝謝您的更正。實際上我還沒有運行代碼(因爲我還沒有解決共享內存問題),所以會導致一些有趣的調試。我也會編輯這個問題。有沒有方法可以在沒有共享內存的情況下修改父級作用域中的變量,還是應該使用共享內存? – stevendesu 2012-01-03 03:00:51