Search code examples
cpipefork

Synchronizing parent and child when using 2 pipes


Here is what my code is intended to do :

The child should:
1. Sends a character to the parent
2. Receive integer from parent and print it

The parent should:
1. Read the character sent from the child and print it
2. Cast it to an integer and send the result to the child

Here is the code I wrote:

#include<stdio.h> 
#include<stdlib.h> 
#include<unistd.h> 
#include<sys/types.h> 
#include<string.h> 
#include<sys/wait.h> 

int main() 
{ 
    int fd1[2];  
    int fd2[2];  

    pid_t p; 

    if (pipe(fd1)==-1) 
    { 
        fprintf(stderr, "Pipe Failed" ); 
        return 1; 
    } 
    if (pipe(fd2)==-1) 
    { 
        fprintf(stderr, "Pipe Failed" ); 
        return 1; 
    } 

    p = fork(); 

    if (p<0) 
    { 
        fprintf(stderr, "fork Failed" ); 
        return 1; 
    } 


   if (p==0){
        char c='a';
      int received;
       close(fd1[0]);   
       write(fd1[1], c, sizeof(char)); 
       close(fd1[1]);

        close(fd2[1]);

       read(fd2[0], received, sizeof(int));
       printf("Printing from child ");
       printf(" ");
       printf("%d", received);
      close(fd2[0]);

   }

   if (p >0) 
    { 

      char received;
      close(fd1[1]);  

         read(fd1[0], received, sizeof(char));
         printf("Printing from parent ");
         printf(" ");
         printf("%c", received);

         close(fd1[0]);
         close(fd2[0]);

         int test=(int)received; 

        write(fd2[1], test, sizeof(test)); 
        close(fd2[1]); 

    } 

} 

My current output is the following: Printing from parent Printing from child 0

I am assuming the parent is reading from the pipe before the child writes to it, how to fix that?


Solution

  • I am assuming the parent is reading from the pipe before the child writes to it, how to fix that?

    This assumption is false. The error is one that a good compiler should have warned about - you missed that not the values of the variables c, received and test have to be passed to write and read, but their addresses:

           write(fd1[1], &c, sizeof(char));
    …
           read(fd2[0], &received, sizeof(int));
    …
             read(fd1[0], &received, sizeof(char));
    …
            write(fd2[1], &test, sizeof(test));
    

    May I ask how the computer ensures the scenario I assumed doesn't happen?

    The read from the pipe, just as with a terminal device, simply blocks until there's something to read (provided that the file descriptor hasn't explicitly been set to non-blocking).