2016-04-07 15 views
1

私は以下のコードから疑わしい点があります。UNIXのpipe&dup関数

#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ファイルディスクリプタも閉じます。 (閉じる(pdf [0])、閉じる(1))。

パイプの一部(pdf [1])を前のstdoutの場所に配置する必要があるため、stdout fdが閉じるはずです。 (DUP(PDF [1]))

しかし、私は、なぜパイプの部分を読むことを得ることができなかった(クローズ(PDF [0])ライトパイプの一部は、(近い(PFD [閉じなければなりません1]))

パイプが双方向であっても、私はそれを使用しないであろうパイプの他の一部を閉塞状態に必要ではないと思う

特に、近い(PDF [1])<。 - この部分は、出力ストリームがない場合(execlp関数を実行する前にstdoutとpdf [1](パイプの書き込み部分)が閉じられたため)、execlp関数の出力はどこに行きましたか?

答えて

3

パイプは双方向ではありません。リードエンドは書き込むことができず、ライトエンドは読み出せません。

パイプ上の読み取り操作では、書き込み終了が開いているプロセスが開いているプロセスがある間は、EOFが報告されません。

したがって、十分なファイル記述子を閉じることが重要です。大まかには、dup2()またはdup()を使用して、パイプの一端を標準入力または標準出力にする場合は、の両方のパイプファイル記述子を閉じる必要があります。

+0

私はパイプの一部を閉じなければならない理由を理解しています。ありがとう。しかし、それでも 'dup'を使用した後、パイプの両側を閉じることについては私には明らかではありません。うーん.. –

+0

あなたはどちらの部分を理解していますか?フォークの後、パイプに4つの端があり、親と子のそれぞれに2つあります。親リードエンドにはP0、親ライトエンドにはP1、子リードエンドにはC0、子書き込みエンドにはC1が使用されます。これらのディスクリプタは閉じても問題ありませんか?あなたが不注意なのかどうかは関係ありませんが、問題が発生したときにプログラムがデッドロックすることがあります。これは、特に非線形パイプライン、または多段パイプラインの場合に当てはまります。 –