2013-02-09 15 views
5

mam eksperymentowanie pewne problemy z tym kodem:połączenia rur i synchronizacja

#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); 
    } 
} 

Kod działa poprawnie, ale nie mogę wyjaśnić, dlaczego! Nie ma wyraźnej synchronizacji między procesami nadrzędnymi i podrzędnymi. Jeśli proces potomny jest wykonywany przed rodzicem, read musi zwracać 0, a proces się kończy, ale z jakiegoś powodu oczekuje na wykonanie nadrzędne. Jak to wyjaśnisz? Może coś mi brakuje.

(Edited)

+2

Dlaczego oczekujesz, że wrócisz 0? Nie ustawiasz niezablokowanych we/wy w dowolnym miejscu. – Mat

+1

... I nie byłoby 0 nawet dla niezablokowanych we/wy. –

+0

Czy "czyta" blokowanie procesu? –

Odpowiedz

5

Ponieważ nie używać O_NONBLOCK w pipe2, read blokuje domyślnie. Dlatego oczekuje na zapisanie danych do potoku.

+0

Kiedy' (fd [0], wiadomość, SIZE)> 0' w warunku while jest fałszywe? –

+0

Staje się fałszywe, gdy rura jest zamknięta na drugim końcu; jeśli nic jeszcze nie napisałeś, czytelnik zakłada, że ​​możesz napisać coś później. IOW potok działa jako niejawna synchronizacja. – loreb

+2

Rura nie jest wcale niejawna. Jest to bardzo jawny mechanizm synchronizacji. Prawdopodobnie najczęściej. Prawdopodobnie także najprostszy. –