2016-05-16 7 views
0

Ich lerne Linux-Systemaufrufe mit C. Ich verstehe die Verwendung von dup2 überhaupt nicht. Bis jetzt habe ich dup2 für 2 Befehle gemacht und es funktioniert in Ordnung, aber ich kann mir keine Möglichkeit vorstellen, 3+ Befehle zu machen.Verwenden Sie den Systemaufruf dup2(), um mehr als 3 Programme zu leiten?

Zum Beispiel, wenn ich will drei Befehle auszuführen:

./program1 
./program2 
./program3 

diese drei Programm ist abhängig von Benutzereingaben Angenommen. Wie kann ich fork() und verwenden, um die Ausgänge dieses Programms zu leiten?

Für nur 2 Befehle Ich habe dies getan, und es wirkt wie ein Zauber:

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

Daumenregel: 1 Satz Rohre für jedes Paar von Prozessen oder '#processes - 1 '. Für 3 Prozesse in der Art wie 'proc1 | proc2 | proc3' brauchst du 2 Sätze Rohre. Der andere Unterschied ist in 'proc2', wo sowohl' stdin' als auch 'stdout' umgeleitet werden. Um 3 Prozesse zu erstellen, müssen Sie 'fork()' von zwei Elternteilen oder 'fork()' von dem Kind, um ein Enkelkind zu machen. – alvits

+0

, Wie Sie schon wissen, wie man 'p1 | p2', denke an 'p1 | p2 | p3 'entweder als' (p1 | p2) | p3' oder 'p1 | (p2 | p3) '. –

+0

kannst du mir bitte sagen wie kann ich den dup2 teil machen? Es ist wirklich verwirrend –

Antwort

0

First off Sie die if-Verschachtelung oder die Dinge sich wirklich unleserlich mit mehr Prozesse in der Pipeline verlieren möchten.

Für 3 verarbeitet das folgende Bash Verhalten zu emulieren ./addone | ./addone | ./addone, Sie möchten etwas schreiben wollen:

#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); 
}