2016-05-16 54 views
0

我正在學習使用C語言的Linux系統調用。我完全不明白dup2的使用。到目前爲止,我做了2個命令dup2,它工作正常,但我想不出做3個以上命令的方法。使用dup2()系統調用管道超過3個程序?

例如,如果我想執行三個命令:

./program1 
./program2 
./program3 

假設這三個程序取決於用戶的輸入。我如何使用fork()dup2()來管理這些程序的輸出?

只有2命令我已經做到了這一點,它就像一個魅力:

pid2=fork(); 
if(pid2==0) 
{ 
    close(pipe1[0]); 
    dup2(pipe1[1], STDOUT_FILENO); 
    close(pipe1[1]); 
    execvp("./addone",argp); 
} 
else 
{ 
    wait(NULL); 
    close(pipe1[1]); 
    dup2(pipe1[0], STDIN_FILENO); 
    close(pipe1[0]); 
    execvp("./addone",argp); 
} 
+1

規則:1套管道的每對流程或'#processes - 1'。以「proc1 |」的方式進行3個進程proc2 | proc3'你需要2套管子。另一個區別是'proc2'中'stdin'和'stdout'都被重定向了。要創建3個進程,你需要從父進程fork()兩次或者從子進程運行fork()來創建一個孫子進程。 – alvits

+0

,正如你已經知道如何使'p1 | p2',想想'p1 | p2 | p3'或者是(p1 | p2)| p3'或'p1 | (p2 | p3)'。 –

+0

你能告訴我如何做dup2部分?它真的讓人困惑 –

回答

0

首先要鬆散的,如果嵌套或​​事情會變得與管道更多的進程確實無法讀取。

對於3流程效仿以下的bash行爲./addone | ./addone | ./addone,你會想要寫的東西,如:拇指

#include <unistd.h>   // dup2(), pipe(), fork(), execvp() 
#include <sys/wait.h>  // waitpid() 
int main() { 
    int pipe1[2], pipe2[2]; 
    int pid0, pid1, pid2; 
    char *argp = {"./addone", "first_argument", "second_argument", NULL}; 

    pipe(pipe1); 
    pid0 = fork(); 
    if (pid0 == 0) { 
     // close the read end of pipe1: 
     close(pipe1[0]); 
     // redirect stdout to the write end of pipe1: 
     dup2(pipe1[1], 1); 

     execvp("./addone", argp); 
    } 

    pipe(pipe2); 
    pid1 = fork(); 
    if (pid1 == 0) { 
     // close the write end of pipe1: 
     close(pipe1[1]); 
     // close the read end of pipe2: 
     close(pipe2[0]);    
     // redirect stdin to the read end of pipe1: 
     dup2(pipe1[0], 0); 
     // redirect stdout to the write end of pipe2: 
     dup2(pipe2[1], 1); 

     execvp("./addone", argp); 
    } 

    pid2 = fork(); 
    if (pid2 == 0) { 
     // close unused pipe1: 
     close(pipe1[0]); 
     close(pipe1[1]); 
     // close the write end of pipe2: 
     close(pipe2[1]); 
     // redirect stdin to the read end of pipe2: 
     dup2(pipe2[0], 0); 

     execvp("./addone", argp); 
    } 

    waitpid(pid0, NULL, 0); 
    waitpid(pid1, NULL, 0); 
    waitpid(pid2, NULL, 0); 
}