2012-02-25 51 views
1

我試圖設置一個程序,使用管道/ execl使用進程間通信在四個進程之間進行通信。這是演示使用管道的作業問題的一部分,但我在圍繞它的過程中遇到了一些困難(即過程樹如何增長)。這些進程是我的系統上的二進制文件的實例,因此使用execl。爲了簡要概述我想要完成的工作,我想將stdin從整個父進程/程序重定向到稱爲「s」的子進程(這是我的系統中稱爲掃描的二進制文件),它將字。在「s」/ scan中,它處理來自stdin的單詞,然後根據單詞將單詞發送/寫入一個進程(「e」)或另一個進程(「o」)。 e/o進程實際上是相同的二進制文件,只是具有符號鏈接 - 它基本上是一樣的。如何在管道/ execl的4個進程之間建立進程間通信的最佳結構?

我該如何去構建我的調用/父程序來構造它?我必須在這個主程序中創建所有進程,否則我只是在掃描/「s」進程中創建兩個子進程。我在下面有一些代碼,我寫了將主程序的stdin重定向到「s」進程,但我不確定在哪裏分叉將連接到它的兩個子進程。我認爲除了「s」/ scan過程之外,還需要創建另外兩個子進程的pid,並將不同的pid作爲參數調用相應的二進制文件,但我不確定。任何幫助將非常感激!

int s_to_e[2]; int s_to_o[2]; 
int e_to_s[2]; int o_to_e[2]; 
pid_t e_pid; pid_t o_pid; pid_t s_pid; 

if (pipe(s_to_e)) {   
     exit(1); 
} 

if (pipe(s_to_o)) {   
     exit(1); 
} 

if ((s_pid = fork()) == -1) { 
     fprintf(stderr, "Fork error! \n"); 
     exit(1); 
} 

int status; 

//Child progress of scan 
if (s_pid == 0) { 
     //Redirect stdin to s 
     //This probably isn't the best way to go about doing this 
     dup2(0, s_to_e[0]); 
     close(s_to_e[1]); 

     //We need to replace the child fork with a new process 
     if(execl("./scan", "./scan", NULL) == -1) { 
      printf("execl Error!"); 
      exit(1); 
     } 

} else { 
     printf("I am parent\n"); 
     wait(&status); 
     printf("Done\n"); 
} 

回答

0

你可以設置一個動態變量在當前進程的數傳,並使用非堵塞IO讀取這將由母公司被寫入管的值。

這意味着,後叉,所述方法應該做的這些:

  1. 回波過程關閉無用管。
  2. 家長讀取一個值(如果失敗,將其設置爲0)。
  3. 父級將增加的值寫入管道。
  4. 孩子execl到相同的程序。

那應該沒問題吧。

0

兩個錯誤在你的問題是:

  • 我想從整體的父進程/程序重定向標準輸入到一個子進程

父母的標準輸入由孩子繼承而不被重定向。

  • 我認爲這將是最好的讓其他兩個子 過程,我需要在除了「S」 /掃描過程 和呼叫建立的PID以不同的pid作爲參數的相應二進制文件

沒有必要將自己的id傳遞給進程;它總是可以通過 getpid()獲得它。

下面的程序應該符合您的要求,除了錯誤檢查。

#define _GNU_SOURCE 
#include <fcntl.h> 
#include <unistd.h> 
#include <stdlib.h> 

main() 
{ 
    int s_to_o[2]; pipe2(s_to_o, O_CLOEXEC); 
    int s_to_e[2]; pipe2(s_to_e, O_CLOEXEC); 
    if (fork() == 0) 
    dup2(s_to_o[1], 1), 
    dup2(s_to_e[1], 2), exit(execl("scan", "scan", NULL)); 
    close(s_to_o[1]); 
    close(s_to_e[1]); 
    if (fork() == 0) 
    dup2(s_to_o[0], 0), exit(execl("o", "o", NULL)); 
    close(s_to_o[0]); 
    if (fork() == 0) 
    dup2(s_to_e[0], 0), exit(execl("e", "e", NULL)); 
    close(s_to_e[0]); 
    wait(NULL); 
    return 0; 
}