2009-02-27 40 views

回答

6

有很多方法可以做到這一點,都涉及某種形式的進程間通信。你選擇哪一個取決於很多因素,但有些是:

  • 共享內存。
  • 管道(popen等)。
  • 套接字。

一般情況下,我可能會在親生父母之前產生若干溝通會話,家長將知道所有五個,但每個孩子可以配置爲只使用一個。

共享內存也是一種可能性,雖然你可能得有幾個值的它每個孩子,以保證通信的順利去了:

  • 存儲變量和返回值的值。
  • 用於存儲狀態的值(0 =開始,1 =變量準備好子項,2 =變量準備好再次爲父項)。

在所有情況下,您都需要一種方式讓孩子只拿起自己的價值觀,而不是那些註定其他孩子的價值觀。這可能就像向共享內存塊添加一個值來存儲子項的PID一樣簡單。所有的孩子都會掃描塊中的每個元素,但只會處理那些狀態爲1,PID是他們的PID的元素。

例如:

  • 主要創建五個孩子共享內存。每個元素都有狀態,PID和值。
  • 主要設置所有狀態爲「開始」。
  • 主要啓動五個全部附加到共享內存的孩子。
  • 主要存儲他們所有的PID。
  • 所有的孩子都開始掃描共享內存,以查看state =「ready for child」及其PID。
  • 主要放入第一個元素(狀態=「準備好孩子」,PID = pid1,值= 7)。
  • 主要放入第二個元素(state =「ready for child」,PID = pid5,value = 9)。
  • 子pid1選取第一個元素,將值更改爲49,將狀態設置爲「準備好父級」),返回監視。
  • 子pid5拾取第二個元素,將值更改爲81,將狀態設置爲「準備好父級」),返回監視。
  • 主拾取pid5的響應,將該狀態設置回「開始」。
  • 主要拿起PID1的響應,設置一個狀態恢復到「開始。

這使並行的措施,每個孩子持續監控它的意思做的工作共享內存,主要場所在那裏工作和週期性地接收結果

+0

我會使用共享內存 – kylex 2009-02-27 06:30:04

+0

您可能不需要執行掃描;孩子們得到一份父母過程數據的副本,所以(不像vfork()例子),孩子們可以看一個櫃檯,告訴他們哪些是他們的。您可以用隨機值預加載內存;那麼孩子們知道數據已經準備好了。 – 2009-02-27 07:59:58

+0

如果你只是分叉(在同一個可執行文件中使用父代碼和子代碼),但如果你要引入子進程,那麼這種方法就行了:進程空間被覆蓋(包括一個計數器)。這些叉子之間共享的東西通常不會給大量危險的事情留下痕跡。不過,這是一個選項。 – paxdiablo 2009-02-27 11:00:38

3

的最惡劣的方法使用vfork()並允許不同的孩子上的存儲器中的不同部分踐踏退出之前;父然後只是增加了存儲器的改性比特

高度不推薦的 - 但有關。只有我合作過的情況我在哪裏vfork()可能實際上有用。

只是爲了取樂(我的)我編寫這件事:

#include <stdio.h> 
#include <unistd.h> 
#include <stdlib.h> 
#include <time.h> 
#include <sys/wait.h> 

int main(void) 
{ 
    int i; 
    int array[5]; 
    int square[5]; 
    long sum = 0; 

    srand(time(0)); 
    for (i = 0; i < 5; i++) 
    { 
     array[i] = rand(); 
     if (vfork() == 0) 
     { 
      square[i] = array[i] * array[i]; 
      execl("/bin/true", "/bin/true", (char *)0); 
     } 
     else 
      wait(0); 
    } 

    for (i = 0; i < 5; i++) 
    { 
     printf("in: %d; square: %d\n", array[i], square[i]); 
     sum += square[i]; 
    } 
    printf("Sum: %d\n", sum); 
    return(0); 
} 

這工作。使用'exit(0)'替代'execl()'的先前試用版本無法使用;方陣是全零。示例輸出(Solaris 10上的32位彙編,SPARC):

in: 22209; square: 493239681 
in: 27082; square: 733434724 
in: 2558; square: 6543364 
in: 17465; square: 305026225 
in: 6610; square: 43692100 
Sum: 1581936094 

有時,總和溢出 - 有很大的空間中的,所述處理的改善。

爲「 vfork()

的的Solaris手冊頁說:

不像叉()函數,子進程借用 父,直到通話記錄和控制線程 的execve()或退出(異常地或通過調用 _exit()(請參閱退出(2))。在此過程中對子進程中任何部分內存進行的任何修改在從vfork()返回的父進程中反映爲 。父母 過程在孩子使用其資源時暫停。

這可能意味着'wait()'在我的代碼中是不必要的。 (但是,試圖簡化代碼似乎使其行爲不確定,i不會過早改變; wait()的確確保了同步性。使用_exit()而不是execl()也似乎破壞了事情。如果不使用vfork() if你重視你的理智 - 或者你想爲你的作業添加任何標記。)

0

the anti thread這樣的東西可能會讓你更容易一些,看例子(尤其是ns查找程序)。

相關問題