Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pipe call and synchronization

Tags:

c

unix

pipe

sync

I'm experimenting some problems with this code:

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

Code works fine but I can't explain why! There is no explicit sync between parent and child processes. If the child-process executes before parent, read must return 0 and the process ends, but for some reason it waits for the parent execution. How do you explain this? Maybe I'm missing something.

(Edited)

like image 915
Fabio Carello Avatar asked Feb 09 '13 12:02

Fabio Carello


1 Answers

Since you didn't use O_NONBLOCK in pipe2, read is blocking by default. Therefore it waits until data are written into the pipe.

like image 179
md5 Avatar answered Sep 22 '22 02:09

md5