Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why should you close a pipe in linux?

Tags:

c

linux

pipe

When using a pipe for process-process communication, what is the purpose of closing one end of the pipe?

For example: How to send a simple string between two programs using pipes?

Notice that one side of the pipe is closed in the child and parent processes. Why is this required?

like image 511
pghazanfari Avatar asked Oct 09 '13 07:10

pghazanfari


People also ask

Why do unused ends of pipes need to be closed?

Each pipe uses two entries in the descriptor table. Closing the unneeded end of the pipe frees up one of those descriptors. So, if you were unfortunate enough to be on a system where each process is limited to 20 descriptors, you would be highly motivated free up unneeded file descriptors.

What happens if you don't close a pipe?

If the parent doesn't close the unused end of the pipe, there will still be two handles for it. If the child dies, the handle on the child side goes away, but there's still the open handle held by the parent -- thus, there will never be a "broken pipe" or "EOF" arriving because the pipe is still perfectly valid.

Why do we need to close a file descriptor when reading or writing to a pipe?

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.

What is the function of pipe in Linux?

In Linux, the pipe command lets you sends the output of one command to another. Piping, as the term suggests, can redirect the standard output, input, or error of one process to another for further processing.


2 Answers

If you connect two processes - parent and child - using a pipe, you create the pipe before the fork.

The fork makes the both processes have access to both ends of the pipe. This is not desirable.

The reading side is supposed to learn that the writer has finished if it notices an EOF condition. This can only happen if all writing sides are closed. So it is best if it closes its writing FD ASAP.

The writer should close its reading FD just in order not to have too many FDs open and thus reaching a maybe existing limit of open FDs. Besides, if the then only reader dies, the writer gets notified about this by getting a SIGPIPE or at least an EPIPE error (depending on how signals are defined). If there are several readers, the writer cannot detect that "the real one" went away, goes on writing and gets stuck as the writing FD blocks in the hope, the "unused" reader will read something.

So here in detail what happens:

  • parent process calls pipe() and gets 2 file descriptors: let's call it rd and wr.
  • parent process calls fork(). Now both processes have a rd and a wr.
  • Suppose the child process is supposed to be the reader.

    Then

    • the parent should close its reading end (for not wasting FDs and for proper detection of dying reader) and
    • the child must close its writing end (in order to be possible to detect the EOF condition).
like image 80
glglgl Avatar answered Sep 21 '22 18:09

glglgl


The number of file descriptors that can be open at a given time is limited. If you keep opening pipes and not closing them pretty soon you'll run out of FDs and can't open anything anymore: not pipes, not files, not sockets, ...

Another reason why it can be important to close the pipe is when the closing itself has a meaning to the application. For example, a common use of pipes is to send the errno from a child process to the parent when using fork and exec to launch an external program:

  1. The parent creates the pipe, calls fork to create a child process, closes its writing end, and tries to read from the pipe.
  2. The child process attempts to use exec to run a different program:
    1. If exec fails, for example because the program does not exist, the child writes errno to the pipe, and the parent reads it and knows what went wrong, and can tell the user.
    2. If exec is successful the pipe is closed without anything being written. The read function in the parent returns 0 indicating the pipe was closed and knows the program was successfully started.

If the parent did not close its writing end of the pipe before trying to read from the pipe this would not work because the read function would never return when exec is successful.

like image 40
Joni Avatar answered Sep 21 '22 18:09

Joni