2016-04-07 1 views
1

У меня есть подозрительный пункт из кода, приведенного ниже.pipe & dup функции в UNIX

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

int main(void){ 

     int pid; 
     int i,j; 
     char c; 

     int pfd[2]; 

     if(pipe(pfd) == -1){ 
       perror("pipe"); 
       exit(1); 
     } 
     // pfd[0] : process read from pfd[0] 
     // pfd[1] : process write to pfd[1] 

     pid = fork(); 

     if(pid == -1){ 
       perror("pid error\n"); 
       exit(1); 
     } 
     else if(pid == 0){ 
       close(pfd[0]); 
       close(1); 
       dup(pfd[1]); 
       close(pfd[1]); 
       execlp("./lcmd", "lcmd", NULL); 
       exit(0); 
     } 
     else if(pid > 0){ 

       wait(NULL); 
       close(pfd[1]); 
       close(0); 
       dup(pfd[0]); 
       close(pfd[0]); 
       execlp("./rcmd", "rcmd", NULL); 
       printf("\n"); 
     } 

     return 0; 
} 

Этот код объясняет, как работать с функцией dup.

Как вы можете видеть, если pid равно 0 (это значит, что происходит дочерний процесс), закройте часть чтения и закройте дескриптор файла stdout. (close (pdf [0]), close (1)).

Я могу понять, что stdout fd должен быть близок, потому что запись части трубы (pdf [1]) должна быть расположена в предыдущем месте stdout. (DUP (PDF [1]))

Однако, я не мог получить, что зачем читать часть трубы (Закрыть (PDF [0]) и запись часть трубы должна быть закрыта (близко (ОФП [ 1]))

Даже если труба является двунаправленным, я думаю, что не нужно государству закрывать другую часть трубы, которая не будет использоваться

Особенно близко (PDF [1]) <.. - эта часть, если нет выходного потока (поскольку stdout и pdf [1] (запись части трубы) были закрыты перед выполнением функции execlp), где был выведен выход функции execlp?

ответ

3

Трубы не двунаправленные - считываемый конец не может быть записан, и конец записи не может быть прочитан.

Операция чтения на трубе не сообщает EOF, пока процесс с открытым концом записи открыт, даже если единственный процесс с открытым концом записи является тем, который пытается прочитать.

Крайне важно, чтобы было достаточное количество дескрипторов файлов. Как правило, если вы используете dup2() или dup(), чтобы сделать один конец трубы стандартным входом или стандартным выходом, вы должны закрыть как дескрипторы файла файла.

+0

Я понимаю, почему одна часть трубы должна быть закрыта. Благодарю. Тем не менее, мне пока не ясно, как закрыть обе стороны трубы после использования «dup». hmm .. –

+0

Какую часть вы понимаете? После развилки в трубе 4 конца, по 2 в родительском и дочернем. Используя P0 для родительского конца чтения, P1 для родительского конца записи, C0 для конца чтения для детей и C1 для конца записи для детей, какие дескрипторы у вас в порядке с закрытием и с какими проблемами вы сталкиваетесь? Обратите внимание, что иногда это не имеет значения, если вы небрежны - но ваша программа может зайти в тупик, когда это имеет значение. Это особенно относится к нелинейным трубопроводам или к многоступенчатым трубопроводам. –