Why should you close a pipe in linux?

后端 未结 3 599
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-04 12:47

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 program

相关标签:
3条回答
  • 2020-12-04 13:00

    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.

    0 讨论(0)
  • 2020-12-04 13:07

    Closing unused pipe file descriptor is more than a matter of ensuring that a process doesn't exhaust its limited set of file descriptor-it is essential to the correct use of pipes. We now consider why the unused file descriptors for both the read and write ends of the pipe must be closed. The process reading from the pipe closes its write descriptor for the pipe, so that, when the other process completes its output and closes its write descriptor, the read sees end-of-file (once it has ready any outstanding data in the pipe). If the reading process doesn't close the write end of the pipe, then after the other process closes its write descriptor, the reader won't see end-of-file, even after it has read all data from the pipe. Instead, a read() would block waiting for data, because the kernel knows that there is still at least one write descriptor open for the pipe.That this descriptor is held open by the reading process itself is irrelevant; In theory, that process could still write to the pipe, even if it is blocked trying to read. For example, the read() might be interrupted by a signal handler that writes data to the pipe. The writing process closes its read descriptor for the pipe for a different reason. When a process tries to write to a pipe for which no process has an open read descriptor, the kernel sends the SIGPIPE signal to the writing process. By default, this signal kills a process. A process can instead arrange to catch or ignore this signal, in which case the write() on the pipe fails with the error EPIPE (broken pipe). Receiving the SIGPIPE signal or getting the EPIPE error is useful indication about the status of the pipe, and this is why unused read descriptors for the pipe should be closed. If the writing process doesn't close the read end of the pipe, then even after the other process closes the read end of the pipe, the writing process will fill the pipe, and a further attempt to write will block indefinitely. One final reason for closing unused file descriptor is that only after it all file descriptor are closed that the pipe is destroyed and its resources released for reuse by other processes. At this point, any unread data in the pipe is lost.

    ~ Micheal Kerrisk , the Linux programming interface

    0 讨论(0)
  • 2020-12-04 13:09

    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).
    0 讨论(0)
提交回复
热议问题