linuxunixiopipe

Named Pipes - Buffering and Blocking


Can someone please clarify behavior of the named pipes (particularly in Linux) regarding buffering data and blocking.

mkfifo pipe1

cat pipe1 # blocks until another process sends data

echo "hi" > pipe1 # running this in the other tty unblocks waiting "cat"

and on contrary (this could be run after previous experiment on the same pipe supposedly):

echo "ping" > pipe1 # blocks, seemingly until another process reads the data

cat pipe1 # unblocks the "echo" above, if run from another tty

Do these both examples block until the "other end" is read/written - or just until the other end is opened at all?

Does the pipe have internal buffer (so that some further writing could be done without block)?

If the process on the "reading" end finishes while some data were not yet consumed from the pipe (or the "writing" process send some more before also finishing) - are these extra data going to appear when the next reading process opens the pipe?

Do we recognize some kind of EOF on the reading end when writing process finishes and we consumed all the data it produced (even though later we can reuse the pipe, writing to it from the other process)?

Sorry if questions are not well-relevant due to misunderstanding of the mechanism. Please feel free to simply provide a link to some advanced documentation.


Solution

  • In your first example

    mkfifo pipe1
    
    cat pipe1 
    
    echo "hi" > pipe1 # from another TTY
    

    the program cat is first blocking in open until the other shell opens the FIFO pipe1 for writing as the shell does the redirection.

    Depending on the timing, it may block in read until echo has written some data.

    When echo ends, its standard output, which is connected to the FIFO, will be closed. This will appear as an end-of-file condition for cat, and it will write remaining output if any and terminate.

    In fact this will happen when the last writing process has closed its end of the FIFO.


    In the second example

    echo "ping" > pipe1
    
    cat pipe1 # from another TTY
    

    the shell will prepare the output redirection for echo. This will block in the open call for the FIFO pipe1 until cat also opens the FIFO.

    After opening the FIFO by the shell, it will be connected to echo's standard output, and echo can write the data without blocking because it is less than PIPE_BUF.

    Depending on the timing, cat might block in read until echo has actually written something.

    If the reading end has been closed by the last process, the writing process will receive a SIGPIPE when it tries to write again.

    Any data in the FIFO is discarded when all processes have closed it.

    (I did not yet find a specification what will happen when all reading processes have closed the FIFO and a new open for reading happens before any writing process has tried to write.)

    See the specification of open, read, write and close and search for "fifo".