2013-02-09 4 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); 
    } 
} 

코드가 잘 작동하지만 난 이유를 설명 할 수 없다! 상위 프로세스와 하위 프로세스 간의 명시적인 동기화는 없습니다. child 프로세스가 parent보다 먼저 실행되면 read는 0을 반환해야하며 프로세스는 종료되지만 어떤 이유로 부모 프로세스가 실행되기를 기다립니다. 어떻게 설명하니? 어쩌면 내가 뭔가를 놓친 것 같아.

(편집)

+2

왜 0이 반환 될 것으로 예상합니까? 어디서나 논 블로킹 I/O를 설정하지 않습니다. – Mat

+1

... 비 차단 입출력의 경우에도 0이되지 않습니다. –

+0

프로세스에 '읽기'가 차단 되었습니까? –

답변

5

당신이 pipe2에서 O_NONBLOCK를 사용하지 않았기 때문에, read은 기본적으로 차단하고 있습니다. 따라서 파이프에 데이터가 기록 될 때까지 대기합니다.

+0

while 조건문이 거짓 일 때'(fd [0], message, SIZE)> 0' 일 때? –

+0

파이프가 다른 쪽 끝에서 닫힐 때 false가됩니다. 아직 아무 것도 쓰지 않았다면 독자는 나중에 뭔가를 쓸 수 있다고 가정합니다. IOW는 암시적인 동기화로 작동합니다. – loreb

+2

파이프가 전혀 암시 적이 지 않습니다. 매우 명시적인 동기화 메커니즘입니다. 가장 일반적인 것 같습니다. 아마도 가장 단순한 것일 수도 있습니다. –