1

Just started learning about pipes (IPC in general). After I went through some man pages, websites and few SO questions like this, This and few others. I got to know the basic and I see that this communication is done only once, i.e., parent writes to child and child reads it or parent and child reads and writes to each other just once and then the pipe closes.

What I want is keep this communication between the processes without the pipe closing, i.e., say, my program has 2 child processes where 1st child process is running something in a while loop and the 2nd is running a timer continuously. At certain intervals, my 2nd process sends some 'signal' to 1st child and my 1st stops and prints something at that instant and restarts again for next timer stop. (<-This I have done using threads)

This is the program that I tried just as a sample. But I'm not able to keep the communication continuous.

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

int main(void)
{
    int     fd[2], nbytes, count = 5;
    pid_t   childpid;
    char    string[] = "Hello, world!\n";
    char    readbuffer[80];

    if((childpid = fork()) == -1)
    {
            perror("fork");
            exit(1);
    }

    if(childpid == 0)
    {
            /* Child process closes up input side of pipe */


            /* Send "string" through the output side of pipe */
            while(count--)
            {
                pipe(fd);
                close(fd[0]);
                write(fd[1], string, (strlen(string)+1));
                close(fd[1]);
            }
            exit(0);
    }
    else
    {
            /* Parent process closes up output side of pipe */
            while(count--)
            {
                pipe(fd);
                close(fd[1]);

            /* Read in a string from the pipe */
            nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
            printf("Received string: %s\n", readbuffer);
            close(fd[0]);
            close(fd[1]);
            }
    }
    int status;
    waitpid(getppid(), &status, 0);

    printf("Done!\n");

    return(0);

}

From those example, I inferred that the pipe get's closed after each send/read. I tried opening new pipe every time, still I could't get it.

Can anyone please help me what am I missing or what should I do?

Community
  • 1
  • 1
vin_
  • 55
  • 3
  • 5
  • Try using named pipes. You can open different named pipes between the parent and as many children as you like. – cup Jun 29 '16 at 17:42

2 Answers2

3

Right now both the parent and child creates their own pair of pipes, that the other process have no knowledge about.

The pipe should be created in the parent process before the fork.

Also, you close the reading/writing ends of the pipe in the loops, when you should close them after the loop, when all the communication has been done.


And a small unrelated issue...

In the reader you should really loop while read doesn't return 0 (then the write-end of the pipe is closed) or -1 (if there's an error).

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • ya but if I close them, then I read that the EOF won't be received and hence the receiving end won't know what is the end point of the input. Right? – vin_ Jun 30 '16 at 05:07
  • @infoseeker If you close the write-end then the read-end will have `read` return `0` (which means "other end closed the file/pipe/connection"). If you close the read-end then the write-end will get a `SIGPIPE` signal, or if you ignore it then `write` will return `-1` with `errno` set to `EPIPE`. – Some programmer dude Jun 30 '16 at 06:37
0

It would be great if you use the shared memory approach. In this approach the parent will allocate a memory area which will be shared among all the processes. Use locks to secure your resource i.e. shared memory. You can also visit this answer which details what is the concept behind. Also remember that in shared memory approach the communication can be many-to-many. But in case of pipes it is one-to-one. Cheers, K. Infoginx.com

Khawar
  • 23
  • 4