next up previous contents index
Next: A.5 Longjmp Up: A. Operating System Concepts Previous: A.3 Sockets   Contents   Index

Subsections


A.4 Pipes

In Unix based operating systems the primary means for inter-process communication is the pipe concept. A pipe is a unidirectional data connection between two processes. A process uses file descriptors to read from or write to a pipe.

A pipe is designed as a queue offering buffered communication. Therefore the operating system will receive messages written to the pipe and make them available to entities reading from the pipe.

The pipe is referenced using file descriptors for both end points. Each endpoint can have more than one file descriptor associated with it.

A.4.1 Using pipes for inter process communication

Most software systems use the functionality and properties of process creation using fork(). Fork copies program, memory and the file descriptor table of the parent to the new child process. When a parent process wants to create a process that it wants to communicate with afterwards, it will create a pipe prior to the process creation. When the new process is spawned, the parent process and all its properties are copied. Therefore the file descriptors containing references to the pipe are copied as well. Now both processes have references to the input and the output end of the pipe. If one process only uses the input end and the other only uses the output end of the pipe, a one-way communication is established between both processes. As pipes can transmit any data as a stream, a pipe can be used to transmit data or simply to synchronize operations between both processes. If two-way communication is desired, two pipes have to be used.

A.4.2 STDIN, STDOUT, STDERR

By default, each process has three file descriptors when it is started. These file descriptors are called STDIN, STDOUT and STDERR. As the names let predict STDIN is the standard means to receive data, STDOUT is used to output data and STDERR is used to transmit error messages. By default these file descriptors are all connected to the shell via pipes that executed the program. A very popular way to establish communication with a child process is to simply redirect the STDIN and STDOUT to a pipe that was created by the parent process prior to spawning the child. However the main advantage is that the newly created process with its redirected pipes can execute a separate program in its own environment using exec(). Although exec() resets the process' memory and loads a new program it keeps the file descriptor table. This program then inherits the process' STDIN and STDOUT which enables communication with the parent process which is then able to interact with the executed external program.

In Apache this is used for external script interpreters. Figure A.7 shows the static structure of such a pipe setup after the STDIN and STDOUT of parent and child have been redirected to a pipe. Another pipe would be needed to establish two-way communication.

A.4.3 Implementation

Pipes are created using the pipe() system call. Pipe() returns an array of file descriptors of size 2. These array elements are used to point to the input and the output end of the pipe. After the successful execution of the pipe function, the pipe can be used for input or output or it can be redirected to any of the standard file descriptors. To achieve that the standard file descriptor in question has to be closed and the other pipe has to be redirected to the standard descriptor using the function dup(), which expects a single integer, the file descriptor identifying the pipe as an argument. Dup actually doubles the output or input to the standard pipe and the supplied argument. But as the standard pipe was closed before calling dup, only the new pipe will be used. By closing all file descriptors of the pipe using close(), the pipe can be closed as well.

Figure A.7: Pipes (View PDF)
Pipes_BD.gif

A.4.4 Named pipes

A drawback of regular pipes lies in the fact that the communication partners have to share file descriptors to get access to the pipe. This can only be done by copying processes with fork().

A named pipe (FIFO) can be accessed via its name and location in the file system. Any process can get access to a named pipe if the access rights of the named pipe allows it to. A named pipe is a FIFO-special file and can be created with the mknod() or mkfifo() system call.


next up previous contents index
Next: A.5 Longjmp Up: A. Operating System Concepts Previous: A.3 Sockets   Contents   Index
Apache Modeling Portal Home Apache Modeling Portal
2004-10-29