2017-03-27 8 views
0

パイプの仕組みを理解しようとしています。私の理解では、カーネルにはファイルディスクリプタテーブルがあり、各要素はファイルやパイプなどを指しています。したがって、正しいファイルディスクリプタが指定されると、プロセスはパイプへの書き込みやパイプからの読み取りが可能です。カーネルのfdテーブルに関してposixパイプに関する混乱

私が下で見つけた例では、ファイルディスクリプタは配列で作成され、それを使ってパイプが作成されます。その後、プログラムはフォークし、子のコピーがあるようにします。これは私が混乱するところです、子供は親から情報を受け取ることができないようにfd [0]を閉じますか?いくつかのデータをfd [1]に書き込みます。親はfd [1]を閉じ、fd [0]から読み込みます。これは私に間違っているようです、親は間違った場所から読んでいますか?

int main(void) 
{ 
     int  fd[2], nbytes; 
     pid_t childpid; 
     char string[] = "Hello, world!\n"; 
     char readbuffer[80]; 

     pipe(fd); 

     if((childpid = fork()) == -1) 
     { 
       perror("fork"); 
       exit(1); 
     } 

     if(childpid == 0) 
     { 
       /* Child process closes up input side of pipe */ 
       close(fd[0]); 

       /* Send "string" through the output side of pipe */ 
       write(fd[1], string, (strlen(string)+1)); 
       exit(0); 
     } 
     else 
     { 
       /* Parent process closes up output side of pipe */ 
       close(fd[1]); 

       /* Read in a string from the pipe */ 
       nbytes = read(fd[0], readbuffer, sizeof(readbuffer)); 
       printf("Received string: %s", readbuffer); 
     } 

     return(0); 
} 

は、私が間違っていると、実際に両方のFDの要素は、カーネルのテーブル内の同じポイントを参照しますか?直感的に私はそれが2つのパイプを作り出すと思っていました。それらがテーブルの同じ位置にある場合、これらの異なる読み書きを解釈できるパイプの構造は何ですか?

これはあまりにも漠然としている場合、私はそれの周りに私の頭を包んで本当の問題を抱えている謝罪します。どんな助けもありがとう。前もって感謝します!

+0

パイプは、* 2つの*ファイル記述子によって特徴付けられるカーネル管理対象オブジェクトです(1つは書き込み用、もう1つは読み取り用)。 'pipe()'関数はそのようなオブジェクトを作成し、2つのFDを指定された配列に記録します。読み込み用のものはインデックス0に、書き込み用のものはインデックス1に格納されます。これはstdinとstdoutファイル記述子(それぞれ0と1)と似ています。使用するつもりのない末端を閉じるためにパイプを使用するプロセスでは、従来の、そして時には必要なことがあります。 –

答えて

0

新しいプロセスforkを実行すると、子プロセスは開いているファイル記述子の正確なコピーを保持します。これがどのように実装されているかは、「魔法のような」ものとみなすことができます。彼らはそれらを共有し、両方が同じ場所から読んでいるので、両方がstdin(たとえば)から読もうとすると、予測不可能な結果が得られます。すべてのプロセスがファイル記述子を閉じると、本当に閉じられるのです。

pipeの場合、子供と親は、気になる終わりが予期せず終了することを心配することなく、使用しないパイプの端を閉じることができます。そのうちの1人が別のファイルを開くと、最近閉じたファイル記述子IDと同じファイル記述子IDを再利用することができます。

関連する問題