JackRobinson
JackRobinson

Reputation: 225

Pipe communicating between the child and the parent using 2 pipes

#include<dirent.h>
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>

int main()
{
    int canal_son[2];
    int canal_father[2];
    pipe(canal_father);
    pipe(canal_son);
    char mesaj_son[20];
    char mesaj_father[20];

    if (fork()==0)
    {
        printf("Son %d\n",getpid());
        read(canal_father[0],mesaj_father,4);
        int j;
        for(j=0;j<5;j++) 
        {
            printf("The message from father is: %s \n",mesaj_father);
            read(canal_father[0],mesaj_father,4);
            write(canal_son[1],"son",3);
        }
        exit(0);
    }

    int i=5;
    for (i=0;i<5;i++)
    {
        write(canal_father[1],"mesas",4);
        read(canal_son[0],mesaj_son,10);
        printf("we are in father:%s\n",mesaj_son);
    }
}

What I am trying to do is create to pipes for communicating between child and father, the only problem is when i try to use both, my process freezes, it is like it's expecting some input, if i only use one pipe, canal_father or canal_son it all works perfectly, does anyone have an idea what is wrong with using 2 pipes?

Thanks a lot.

Upvotes: 0

Views: 959

Answers (3)

Chris Dodd
Chris Dodd

Reputation: 126243

The way your code is structured, the son tries to read TWO messages from the father before it writes one, while the father writes ONE message and then tries to read one. So the son blocks on the second read (the one in the loop, with j=0), while the father blocks on the first read (i=0).

Also, since you never close any of write ends in either process (there are 4 -- two in the son and two in the father), you'll never get any EOFs on read. This isn't really a problem here, since you never wait for an eof, but may become a problem if you try to do more complex things.

Finally, the messages you're writing don't include the terminating NUL ('\0') for the strings, so when you pass them the printf, they are unterminated, which will lead to problems. You need to either include the NULs in the data written, or get the length read from the read calls (the return value) and terminate the strings explicitly.

In any case, you should check the return value of the read and write calls for errors.

Upvotes: 1

spbnick
spbnick

Reputation: 5275

Your child is attempting to read twice from the parent's pipe. As a result both child and parent wait for each other to start writing.

The full sequence of events is this:

  1. Parent writes to the child.
  2. Child reads from the parent.
  3. Parent waits to read from the child.
  4. Child waits to read from the parent.

To fix this, remove extra read from the start of the child and move printout after the reading in the loop. So the child code looks like this:

    printf("Son %d\n",getpid());
    int j;
    for(j=0;j<5;j++) 
    {
        read(canal_father[0],mesaj_father,4);
        printf("The message from father is: %s \n",mesaj_father);
        write(canal_son[1],"son",3);
    }
    exit(0);

Upvotes: 1

parkydr
parkydr

Reputation: 7782

You're reading and writing different sized, unterminated strings and doing different numbers of reads and writes. If you make the sizes and reads/write consistent, it works.

if (fork()==0)
{
    printf("Son %d\n",getpid());
    int j;
    for(j=0;j<5;j++)
    {
        printf("The message from father is: %s \n",mesaj_father);
        read(canal_father[0],mesaj_father,6);
        write(canal_son[1],"son",4);
    }
    exit(0);
}

int i=5;
for (i=0;i<5;i++)
{
    write(canal_father[1],"mesas",6);
    read(canal_son[0],mesaj_son,4);
    printf("we are in father:%s\n",mesaj_son);
}

Upvotes: 1

Related Questions