views:

523

answers:

4

Here is an example to illustrate what I mean:

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

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

        pipe(fd);

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

        if(childpid == 0)
        {
                /* Child process closes up input side of pipe */
                close(fd[0]);

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

            /* Read in a string from the pipe */
            nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
            printf("Received string: %s", readbuffer);
    }

   return(0);

}

However, what if one of my processes needs to continuously write to the pipe while the other pipe needs to read?

The example above seems to work only for one write and one read.

+3  A: 

After performing the fork, all fds are duplicated. Each process has both ends of the pipe open. If you only want to use one end you should close the other (if your process writes, close the read end).

Besides the obvious fact that if you do not close the descriptors the OS will keep extra entries in the open file table, if you do not close the write end of the pipe, the reader will never receive EOF since there is still a way of entering data into the pipe. AFAIK (and IIRC) there is no problem in not closing the read fd in the other process --that is, besides the file being open for no reason.

It is also recommended (as good practice, not that it affects too much) that you close all descriptors before exiting the application (that is, closing the other end of the pipe after the read/write operation is completed in each process)

David Rodríguez - dribeas
A little clarification, I don't create a processes but thread, and I pass write end of the pipe to the thread to use to write
Why do you fork then? fork doesn't create threads, it creates child processes.
qrdl
That was just an example. I actually start a separate thread from the processes.
Then it is completely different environment - you just misled people. Now I understand why this question was downvoted.
qrdl
any suggestions?
I have one, edit your whole question so that it's clear what you ACTUALLY wants. Then give all the answers here an up vote for taking their time to respond.
Skurmedel
+4  A: 

Your pipe is a unidirections stream - with a file descriptor for each end. It is not neccessary to close() either end of the pipe to allow data to pass along it.

if your thread spans processes (i.e. is created before a fork() and then the parent and child use it to communicate) you can have one write and and one read end. Then it is good practice to close the unwanted ends of the pipe. This will

  • make sure that when the writing end closes the pipe it is seen by the read end. As an example, say the child is the write side, and it dies. If the parent write side has not been closed, then the parent will not get "eof" (zero length read()) from the pipe - because the pipe has a open write-end.
  • make it clean which process is doing the writing and which process is doing the reading on the pipe.

if your pipe spans threads (within the same process), then do not close the unwanted ends of the pipe. This is because the file descriptor is held by the process, and closing it for one thread will close it for all threads, and therefore the pipe will become unusable.

There is nothing stopping you having one process writing continuously to the pipe and the other process reading. If this is a problem you are having then give us more details to help you out.

Beano
I only have one reader - parent, and one writer -- child thread –
If you are in a threaded environment, then the file descriptors are shared by the various threads. So in these circumstances DO NOT close the read/write end of the pipe until you have completely finished, otherwise the pipe will close down. I now understand the question - when the pipe spans processes, close the unwanted ends, when the pipe spans threads (within a process), so not close the unwanted ends.
Beano
A: 

A pipe won't give you a bidirectionnal channel, neither will it be multicasting. A pipe as only two ends, it does not have one write end and multiple read end.

If you want many readers, then you need as many pipe as you have reader process.

shodanex
I only have one reader - parent, and one writer -- child thread
A: 

"The example above seems to work only for one write and one read."

That is because after one read and write your code exits. You need to keep writing in a loop and reading in a loop to achieve continuity. It does not seem to have anything to do with the FD close. As mentioned in an earlier reply you need one end on each process so the other is closed.

I hope I understand the query right.

Naunidh