2015-12-14 6 views

Odpowiedz

5

Nie są one całkiem takie same w tym sensie, że wywołanie pipe(2) nie wystarczy do zaimplementowania równoważnej funkcji powłoki |.

pipe(2) tworzy dwa deskryptory plików (przeczytaj koniec i koniec zapisu). Ale musisz zrobić więcej, aby zaimplementować funkcjonalność |.

Typowa sekwencja tworząc rurę idzie tak:

1) Utwórz odczytu koniec i koniec zapisu przy użyciu pipe(2).

2) Utwórz proces potomny za pomocą fork().

3) Procesy macierzyste i podrzędne duplikują deskryptory plików przy użyciu dup2().

4) Oba procesy zamykają jeden koniec rury (jeden koniec rury, którego nie używa każdy proces).

5) Jeden pisze do rury i inne odczyty z rury.

Rozważ prosty przykład, aby to pokazać. W tym przypadku przekazujemy nazwę pliku jako argument, a proces nadrzędny "przegląda" plik, który jest podrzędny dla pliku cat.

#include <stdio.h> 
#include <unistd.h> 

int main(int argc, char **argv) 
{ 
    int pipefd[2]; 
    int pid; 

    char *cat_args[] = {"cat", argv[1], NULL}; 
    char *grep_args[] = {"grep", "search_word", NULL}; 

    pipe(pipefd); 
    pid = fork(); 

    if (pid != 0) 
    { 
     dup2(pipefd[0], 0); 
     close(pipefd[1]); 
     execvp("grep", grep_args); 
    } 
    else 
    { 
     dup2(pipefd[1], 1); 
     close(pipefd[0]); 
     execvp("cat", cat_args); 
    } 
} 

Odpowiada to robi

cat file | grep search_word 

na skorupce.

+0

Dlaczego tworzone są duplikaty? czy nie możemy pisać i czytać danych bez duplikowania? –

+1

Nie jest to bezwzględnie konieczne ('dup2()') we wszystkich procesach komunikacji rodzic-dziecko. Ty rodzic i dziecko również potraficie komunikować się bezpośrednio. Na przykład rodzic może "napisać (2)" na końcu zapisu rury, a element potomny może "odczytać (2)" z końca odczytu. –

+0

@PsAkshay, ponieważ wykonane grep i cat tylko odczyt/zapis z 0 i 1, a nie pipefd's. –

6

Rura osłonowa | jest zaimplementowana przy użyciu wywołań systemowych pipe(2) i dup2(2).

Zobacz Unix Pipes.

0

pipe(2) syscall wykorzystywane przez powłoki dla rurociągów z operatorem

|| jest wykonanie powłoki, to intenally wykorzystuje pipe() wywołania systemowego.