2012-10-03 28 views
0

我正在嘗試創建一個進程的二叉樹,其中每個父進程通過管道連接到其兩個子進程。如何管理上升的管道和管道沿進程的二叉樹?

問題:父進程A創建兩個進程(B和C)和兩個管道,每個進程一個進程。他們的文件描述符被存儲到fd中。在第二次迭代中,B產生了兩個孩子。 B用新管道的文件描述符覆蓋存儲在fd中的文件描述符。在產卵了n個關卡之後,剩下的唯一管道就是父母的葉節點(上一層)。

我已經測試了這個理論,唯一傳達的東西是在樹的底部,葉到上一層之間。我必須做到這一點,因此葉節點可以在樹的主進程中進行通信。

我是新來的管道,所以我可以關閉我的解釋。

我的理解是否正確,我該如何解決此問題?

示例代碼:

#define READ 0 
#define WRITE 1 

int fd[2][2]; 

void 
spawnChildren(int levels) 
{ 
    if(levels == 0) 
     return; 

    pipe(fd[0]); 
    //spawns 2 children at a single parent 
    int pid = fork(); 
    //parent 
    if(pid > 0) 
    { 
     close(fd[0][WRITE]); 
     pipe(fd[1]); 
     int pid2 = fork(); 
     //child B 
     if(pid2 == 0) 
     { 
      close(fd[1][READ]); 
      spawnChildren(levels-1); 
      return; 
     } 
     //parent 
     else 
      close(fd[1][WRITE]); 
    } 
    //child A 
    else 
    { 
     close(fd[0][READ]); 
     spawnChildren(levels-1); 
     return; 
    } 
} 
+1

希望你不需要太多的過程。製作一棵小樹可能是可以的,但試圖構建一個擁有數千個獨立進程的樹可能不會擴展。 –

+1

看來你並沒有將管道跟蹤到任何地方的父進程?除根和葉以外的每個進程都需要跟蹤三個管道 - 每個子進程一個,其父進程一個。 – twalberg

+0

爲了跟蹤管道上升,我應該使用dup2嗎?例如:父母的左側閱讀將相當於左側孩子的寫作管道。那是對的嗎? –

回答

0

如果我理解正確,根進程打開 FD與它的兩個孩子溝通。然後,他們只需打開其他獨立的管道。

當他們的四個?根過程如何與其侄子溝通?

您需要保留全部 fd's open;每個進程必須從其子進程獲得輸入,並將其傳遞給其父進程;你需要某種協議來整理它們。數據也一樣。

例如,根家長都希望其左孩子的右孩子的左孩子溝通:

  • 發送RL.HELLO全世界將其左子
  • 左子看到R和發送# L.HELLO WORLD其右孩子
  • 正確的孩子接受#L.HELLO世界發送##。HELLO WORLD其左子
  • 左孩子接受##。HELLO WORLD,知道消息的吧

  • 左子答案發送##。我聽說你給其父

  • 父看到其左孩子交談,最後#轉換爲L和發送了
  • 家長認爲其右子說#李聽到你和發送RL.I聽到你了
  • 根接收RL.I從它的左孩子聽到你和誰知道它起源

當然,在這一點上每個進程還必須有一個隊列傳入和傳出的消息。

即使僅在根和樹葉之間進行通信,也需要隊列和消息傳遞;它只會允許沒有「R#L」協議,但考慮到其簡單性,這是一個非常小的節約。

+0

消息傳遞只會增加,這意味着孩子是唯一能夠寫給他們父母的人。父母是唯一能夠從他們各自的孩子讀取的人。消息傳遞不需要。這個程序的應用是在一個並行的外部合併排序中。 –

0

您需要的是一個線程或進程監聽(讀取)每個管道,然後將其寫入相應的管道。基本上每個'節點'需要兩個線程或進程來完成這個任務,每個子進程都有一個線程或進程。

這不是很有伸縮性,並且取決於你想要做什麼,如果你不能更好地設計它,你可能需要重新評估。一個建議是讓你的葉節點寫入臨時文件而不是管道,然後讓你的頂層智能地讀取這些文件,而不是試圖通過叉來管理所有這些管道。這樣做可以大量減少'節點'的數量。只是一個想法。