0
votes

As I have just started with these concepts I might be missing out a few elementary things. I was trying to link the parent and the child processes (created by fork() function) using pipe. In the parent process, I wanted to write in the pipe descriptor (af[1]) and after closing up the write end, I wanted to read from the read end of the pipe with descriptor (af[0]) in the child process.

Here is my code:

#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <cstdlib>
#include <sys/wait.h>
#include <sys/types.h>
#include <string.h>
using namespace std;

int main()
{
    pid_t pid1;
    pid1 = fork();

    int af[2],nbytes,wbytes;
    pipe(af);
    char inside[20];

    if(pid1 == -1)
    {
        cout << "No child process formed: " << getpid() <<endl;
        exit(1);
    }
    else if(pid1 == 0)
    {   cout<< "inchild" <<endl;
        close(af[1]);
        nbytes = read(af[0],inside,strlen(inside));
            cout << "read bytes: "<< nbytes << endl;
        cout << "child(read) inside descriptor: " << inside << endl;
        close(af[0]);
        cout << "in child's end" << endl;
        exit(0);
    }   
    else
    {   cout<< "inparent" << endl;
        close(af[0]);
        wbytes = write(af[1],"Hello World",12);
        cout<< "wrote bytes: " << wbytes<<endl;
        cout << "Parent(write) inside string: " << af[1] << endl;
        close(af[1]);
        cout << "in parent's end" << endl;
        exit(0);
    }

    return 0;

}

Then I was expecting this to run as follows:

  • Goes into the parent -> write string,
  • Close write end,
  • Goes into the child -> read string into inside,
  • Show result of string (Hello World),
  • Close read end.

But what I was getting here is this result:

inparent
shashish-vm@shashishvm-VirtualBox:~/Desktop$ inchild
read bytes: 0
child(read) inside descriptor: 
                               A��M�N��sf�
in child's end

And it was still not terminating.

I was using Ubuntu 14.04 LTS on Oracle VM VirtualBox (32-bit O.S.). And I have no idea why it was doing like this. I knew it is the job of the scheduler to switch the processes but still pipe functionality of IPC was not working there. The write process occurred even if I removed close(af[0]) statement but still the reading was not happening properly.

1
sizeof(inside) not strlen(inside) in read() callSlava
In C++, char size is of 1 byte, so it doesn't matter much. But yeah, ideally, I should have used that. Thanks.Shashish Chandra
It does matter. inside is unitialized so strlen() returns garbage value, you can get all unpredictable results with it, including program crash.Slava
Yeah. That's one of those cases when the child is scheduled earlier than the parent. But scheduler is working the other way here. So, it has been assigned a value in the parent already. So, ya, I should have taken care of this thing. Thanks for the help. :-)Shashish Chandra
First of all you do not touch inside in the parent process. Second - it does not matter, as after fork() those are 2 separate processes and changing memory in one process does not affect it in another (unless it is another IPC - shared memory). How they are scheduled completely unrelated. Third, using strlen() in this case not a good idea anyway, even if it is properly initialized.Slava

1 Answers

2
votes

You problem is that you open the pipe after calling fork. This means the parent and child have different pipes. You can fix it by moving the call to pipe before the fork to create a single linked pipe.