2013-02-09 14 views
5

私はこのコードでいくつかの問題を試しています:パイプコールと同期

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

#define SIZE 30 
#define Error_(x) { perror(x); exit(1); } 
int main(int argc, char *argv[]) { 

    char message[SIZE]; 
    int pid, status, ret, fd[2]; 

    ret = pipe(fd); 
    if(ret == -1) Error_("Pipe creation"); 

    if((pid = fork()) == -1) Error_("Fork error"); 

    if(pid == 0){ //child process: reader (child wants to receive data from the parent) 
     close(fd[1]); //reader closes unused ch. 
     while(read(fd[0], message, SIZE) > 0) 
       printf("Message: %s", message); 
     close(fd[0]); 
    } 
    else{//parent: writer (reads from STDIN, sends data to the child) 
     close(fd[0]); 
     puts("Tipe some text ('quit to exit')"); 
     do{ 
      fgets(message, SIZE, stdin); 
      write(fd[1], message, SIZE); 
     }while(strcmp(message, "quit\n") != 0); 
     close(fd[1]); 
     wait(&status); 
    } 
} 

コードが正常に動作しますが、私は理由を説明することはできません!親プロセスと子プロセスの間に明示的な同期はありません。子プロセスがparentの前に実行される場合、readは0を返さなければならず、プロセスは終了しますが、なんらかの理由で親プロセスが実行されるのを待ちます。これはどうやって説明しますか?たぶん私は何かが欠けているでしょう。

(編集後)

+2

なぜあなたは0が返されると思いますか?ノンブロッキングI/Oはどこにも設定していません。 – Mat

+1

...ノンブロッキングI/Oの場合でも0にはなりません。 –

+0

プロセスの 'read'ブロックはありますか? –

答えて

5

あなたはpipe2O_NONBLOCKを使用していなかったので、readはデフォルトでブロックしています。したがって、データがパイプに書き込まれるまで待機します。

+0

while条件の'(fd [0]、message、SIZE)> 0'がfalseのときは? –

+0

パイプがもう一方の端で閉じている場合はfalseになります。まだ何も書いていないのであれば、読者は後で何かを書いておきたいと思います。パイプは暗黙同期として機能します。 – loreb

+2

パイプはまったく暗黙的ではありません。これは非常に明示的な同期メカニズムです。おそらく最も一般的です。おそらく最も簡単かもしれません。 –