Working with Named Pipes

Pipes allow processes to communicate with each other. A pipe may also be known as a "FIFO" (First In, First Out).

The advantage over using files as a means of communication is, that processes are synchronized by pipes: a process writing to a pipe blocks if there is no reader, and a process reading from a pipe blocks if there is no writer.

The following is an example on how to create a named pipe, named here as pipe1.

 cd /tmp
 mkfifo pipe1

To send a message to the pipe, use:

 echo "hello" > pipe1

The process will appear to be hung at this point. There is no other process running to collect the data, so the kernel suspends the process. The process is said to be "blocked" at this stage.

On another terminal, it is possible to collect the data from the pipe, as follows:

 cat /tmp/pipe1

The data from the pipe will now be read by cat (and written to the terminal), and the "blocked" writer process will be free to resume.

For some more information, see Bash FAQ #85.

Synchronous bidirectional Client - Server example

Here is a small example of a server process communicating with a client process. The server sends commands to the client, and the client acknowledges each command:

Server

# server - communication example

# Create a FIFO. Some systems don't have a "mkfifo" command, but use
# "mknod pipe p" instead

mkfifo pipe

while sleep 1
do
    echo "server: sending GO to client"

    # The following command will cause this process to block (wait)
    # until another process reads from the pipe
    echo GO > pipe

    # A client read the string! Now wait for its answer. The "read"
    # command again will block until the client wrote something
    read answer < pipe

    # The client answered!
    echo "server: got answer: $answer"
done

Client

# client

# We cannot start working until the server has created the pipe...
until [ -p pipe ]
do
    sleep 1;    # wait for server to create pipe
done

# Now communicate...

while sleep 1
do
    echo "client: waiting for data"

    # Wait until the server sends us one line of data:
    read data < pipe

    # Received one line!
    echo "client: read <$data>, answering"

    # Now acknowledge that we got the data. This command
    # again will block until the server read it.
    echo ACK > pipe
done

Write both examples to files server and client respectively, and start them concurrently to see it working:

    $ chmod +x server client
    $ server & client &
    server: sending GO to client
    client: waiting for data
    client: read <GO>, answering
    server: got answer: ACK
    server: sending GO to client
    client: waiting for data
    client: read <GO>, answering
    server: got answer: ACK
    server: sending GO to client
    client: waiting for data
    [...]


CategoryShell CategoryUnix

NamedPipes (last edited 2012-07-21 09:01:02 by 77)