Here is the code:
int main() {
int fd[2];
pipe(fd);
int r = fork();
if (r > 0) { //parent
close(fd[0]);
// do a bunch of things
} else { //child
close(fd[1]);
// do a bunch of things
return 0;
}
This is a piece of code where the parent writes to the pipe and child reads from the pipe. My question is: for the two close statements, what exactly are they closing? The parent and the child should share the same file, i.e. fd[0] and fd[1]. If fd[0] is closed in the parent, shouldn't it also be closed in child?
Since descriptors are shared between the parent and child, we should always be sure to close the end of pipe we aren't concerned with. On a technical note, the EOF will never be returned if the unnecessary ends of the pipe are not explicitly closed.
Until every FD referring to the write end of a pipe is closed, it won't return EOF.
close() closes a file descriptor, so that it no longer refers to any file and may be reused.
If you close fd[0] in parent and also in child there is from nowhere you can read from the pipe, in the reverse case if you close fd[1] in both the processes you cannot write into pipe, So we close the read descriptor in one process so that the process can only write and the other process will close write descriptor ...
From http://linux.die.net/man/2/pipe pipe()
creates a pipe which consists of two file descriptors which correspond with the two "ends" of the pipe, the read end and the write end. It's not really the same thing as a file. The kernel is reading data from the write end, buffering it for you, and transferring it it to the read end.
This should make it obvious why pipe()
creates two file descriptors. The writer writes all the data it needs into the write fd and closes the fd. This also triggers an EOF
to be sent. The reader would usually keep reading data until it encounters the EOF
and closes its end. In this scenario, there's a period of time where the write fd is closed but data is still buffered in the pipe, waiting to be read out by the reader. It doesn't make sense to have a single fd, as you'll need another layer of coordination between the writer and reader processes, otherwise who will do the closing, and when?
The pipe() call always returns an integer array where the first element of array is the read descriptor to read from pipe and second element is the write descriptor to write into the pipe. The pipes provide one way communication. If you close fd[0] in parent and also in child there is from nowhere you can read from the pipe, in the reverse case if you close fd[1] in both the processes you cannot write into pipe, So we close the read descriptor in one process so that the process can only write and the other process will close write descriptor which will enable the process to only read from pipe.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With