2013-02-09 26 views
5

Bu kod ile bazı sorunlar deniyorum:boru çağrı ve senkronizasyon

#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 çalışıyor ama neden açıklayamam! Ebeveyn ve çocuk süreçleri arasında açık bir senkronizasyon yoktur. Alt işlem, ana işlemden önce yürütülürse, okuma 0'a dönmeli ve işlem bitmeli, ancak bazı nedenlerden dolayı üst yürütmeyi bekler. Bunu nasıl açıklıyorsunuz? Belki bir şey özlüyorum.

(Düzenleyen)

+2

Okumanın neden geri dönmesini beklersiniz? Hiçbir yerde engellemeyen G/Ç ayarlamıyorsunuz. – Mat

+1

... Ve engellemeyen G/Ç için bile 0 olmaz. –

+0

İşlem için "engelleme" engellendi mi? –

cevap

5

Eğer pipe2 içinde O_NONBLOCK kullanmıyordu beri read varsayılan olarak engelliyor. Bu nedenle, veriler boruya yazılana kadar bekler.

+0

Koşul() 'da iken (fd [0], ileti, SIZE)> 0' olduğunda? –

+0

Boru diğer tarafta kapatıldığında yanlış olur; Henüz bir şey yazmadıysanız, okuyucu daha sonra bir şeyler yazmak isteyebileceğinizi varsayar. IOW boru, örtük bir senkronizasyon olarak davranır. – loreb

+2

Boru hiç örtük değildir. Çok açık bir senkronizasyon mekanizmasıdır. Muhtemelen en yaygın. Muhtemelen en basit olanıdır. –