2016-10-18 17 views
0

私のプログラムは子プロセスを作成し、それに通信するパイプを設定します。この問題は、パイプからデータを読み取ろうとしたときに発生します。子プロセスは終了しています(私はwaitを使用しています)。EOFはデータストリームの最後になければなりません。このため、読み込みが終了します(マニュアルページのpipe)。しかし、代わりにreadはフリーズし、さらにデータが来るのを待ちます。 ここには何が欠けていますか?子プロセスが終了したのでパイプからすべてのデータを読み取るC

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/wait.h> 



void setfd(int *in, int *out) { 
    dup2(out[1], 1); 
    dup2(in[0], 0); 
} 

int main(int argc, char *argv[]) { 
    int status; 
    int pipe2ch[2], pipe2pr[2]; 
    char *newargv[] = {NULL, NULL}; 
    newargv[0] = argv[1]; 

    pipe(pipe2ch); 
    pipe(pipe2pr); 

    setfd(pipe2pr, pipe2ch); 
    int a; 
    if (!(a = fork())) { 
     setfd(pipe2ch, pipe2pr); 
     execve(newargv[0], newargv, NULL); 
     exit(1); 
    } else { 
     printf("hello!\n"); 
     fflush(stdout); 

     char str; 

     wait(&status); 
     while (read(pipe2pr[0], &str, 1) > 0) { 
      fprintf(stderr, "%c", str); 
     } 
     exit(0); 
    } 
} 
+1

親プロセスは 'pipe2pr [1]'を終了する必要があります。 EOFを得ること自体が妨げられています。 – kaylum

答えて

1

EOFは、このように(パイプのmanページのように)の読み取りを終了するデータストリームの最後にする必要があります(私はそれを確実にするために待機を使用します)。

私はあなたがそれを示唆するために読んだことがわかりません。それともあなたが私が理解していない言葉です。 EOFはストリーム上の文字ではありません。

しかし、代わりに読み込みをフリーズし、さらにデータが来るのを待ちます。私はここで何が欠けていますか?

いくつかのことがあります。最も重要なのはおそらく、プロセスがフォークするとき、親のオープンファイル記述子の子のコピーは、カーネルのオープンファイルの親テーブルと同じエントリを参照し、それぞれがまで開いたままであることです。それは閉じています。子が終了するときに子がすべてのファイル記述子を閉じますが、両方のパイプの両端が親の中で開いたままのままです。ファイルの終わりが読者に通知されません。各プロセスは、使用しないか、使用を終了したパイプの端を閉じる必要があります。

さらに、最初にwait()を入力してください。子プロセスが十分なデータをパイプに書き込むと、ブロックされ、子プロセスが終了するまで親プロセスが読み取られない場合、デッドロックが発生します。

さらに、パイプの端を親の標準ストリームに捨てて、元のストリームを閉じてしまう理由はありません。すでに半分のように、ファイル記述子でパイプを操作するだけです。それらにストリームインターフェイスを使用する場合は、fdopen()を使用して取得します。

関連する問題