2016-12-12 78 views
0

我正在使用C字符串在管道系統上工作。例如,我將此行寫入控制檯./pipeline LOWERCASE REVWORD SQUASHWS < stringFile.txt。它應該是這樣的P0 - > P1 - > P2 - > ...-> Pn。 P0從文件stringFile.txt加載字符串並將其發送到P1 ..我可以使用管道(發送和讀取),但我不知道如何處理N個進程。它應該是這樣的。你能給我任何建議或例子嗎?謝謝帶字符串的管道系統

while(is_something_to_read) { 
    load_from_previous_process(); 
    do_process(); // for example LOWERCASE 
    send_to_next_process(); 
} 

回答

0

帕特里克,

我寫的模擬外殼,將產生孩子一定量,然後將每個過程與另一個進程通信的程序。由於進程的數量可能會有所不同,我決定使用二維數組作爲管道。在下面的代碼中,NUM_PROCS指的是將要運行的進程的數量(包括父進程)。

我宣佈它

int pipes[NUM_PROCS][2]; 

在此之後,我創建了管道

for(i = 0; i < NUM_PROCS; i++) 
{ 
    if((pipe(pipes[i])) < 0) 
    { 
     perror("Failed to open pipe"); 
    } 
} 

這是我寫的實踐shell程序。

#include <errno.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <fcntl.h> 

#define MAXARGS 256 
char ** getargs(char * cmd) { 
     char** argsarray; 
     int nargs = 0; 
     int nlen = strlen(cmd); 
     int i = 0; 
     argsarray = (char**) malloc(sizeof(char*) * MAXARGS); 
     argsarray[0] = strtok(cmd," "); 
     i = 0; 
     while (argsarray[i] != NULL){ 
       i++; 
       argsarray[i] = strtok(NULL," "); 
     } 
     return argsarray; 
} 


int main(void){ 

    pid_t childpid; 
    int fd[256][2]; 
    char cmd[256]; 
    char * sepCmd[256]; 
    char * pch; 

    printf("Please enter a command sequence: \n"); 
    gets(cmd); 
    printf("You have entered: %s ....%d\n", cmd,strlen(cmd)); 


    printf("Attempting to split up command: \n"); 
    pch = strtok (cmd, "|"); 
    int count = 0; 
    while (pch != NULL && count < 256) { 
     printf("%s\n", pch); 
     sepCmd[count] = pch; 
     printf("The value in this array value is: %s\n", sepCmd[count]); 
     pch = strtok (NULL, "|"); 
     count++; 
    } 

    char ** argue; 
    int k; 

    /* Block that deals with the first command given by the user */ 
    k = 0; 
    pipe(fd[k]); 
    if(!fork()) { 
       dup2(fd[k][1], STDOUT_FILENO); 
       close(fd[k][0]); 
       argue = getargs(sepCmd[k]); 
       execvp(argue[0], argue); 
       perror(argue[0]); 
       exit(0); 
    } 

    /*Loop that will control all other comands except the last*/ 
    for(k = 1; k <= count - 2; k++) { 
      close(fd[k-1][1]); 
      pipe(fd[k]); 

      if(!fork()) { 
        close(fd[k][0]); 
        dup2(fd[k-1][0], STDIN_FILENO); 
        dup2(fd[k][1], STDOUT_FILENO); 
        argue = getargs(sepCmd[k]); 
        execvp(argue[0], argue); 
        perror(argue[0]); 
        exit(0); 
      } 
    } 
    /*Block that will take care of the last command in the sequence*/ 
    k = count - 1; 
    close(fd[k-1][1]); 
    if(!fork()) { 
      dup2(fd[k-1][0], STDIN_FILENO); 
      argue = getargs(sepCmd[k]); 
      execvp(argue[0], argue); 
      perror(argue[0]); 
      exit(0); 
    } 
    while(waitpid(-1, NULL, 0) != -1); 
} 
+0

你能告訴我任何示例它是如何工作的? – PatrikD

+0

@PatrikD一旦你編譯你的程序,你會得到a.out。運行該可執行文件你會被問到「請輸入命令序列:」然後給ps -aux或任何shell命令 –

+0

Okey它正在工作,但我不知道如何處理例如p1進程LOWERCASE的進程併發送到P2進程REVWORD。你的例子有可能嗎? – PatrikD