Pipes in *NIX Systems
Pipes, how they work, their types and how to implement a pipe yourself.
Pipes were one of the first interprocess communication (IPC) mechanisms implemented in early UNIX systems. They are used as a way to communicate between two processes, and as a form of redirection to send the output of one program to another program for processing. Pipes can be unidirectional or bidirectional, which defines how data travels in the pipe. In a unidirectional pipe data travels in only one direction, whereas in a bidirectional pipe data can travel in both directions.
I/O on pipes
Unix treats pipes as a special type of files. Thus, they can be accessed using write()
and read()
.
A pipe has two end, a read-end and a write-end. Data written to the write-end can be read from the read-end. Its limited in capacity, so if a process tries to write (via write()
) to a filled pipe it blocks until a space is available in that pipe. When a process tries to read (via read()
) from an empty pipe it must wait until data is available.
Types of pipes
Two common types of pipes are: ordinary pipes and named pipes. Ordinary pipes are unidirectional and can only be accessed by the process that created them. Named pipes, on the other hand, are bidirectional and are not restricted to the process that created them.
Implementing a pipe
Below is the source code for an ordinary pipe implemented in C language. It creates a pipe using pipe()
syscall and forks a child using fork()
syscall. pipe()
takes an array of two integers and stores the file descriptors (fd) of the pipe read and write ends in it, where the first index contains the read-end fd and the second index contains the write-end fd.
fork()
returns the process identifier (PID) of the child process it creates and if it failed it returns -1.
This is it, we now have an ordinary pipe with parent-child relationship. Pipes are an awesome feature, if you used Linux or any UNIX-like systems you might have piped an output of one command to another command, for example:
cat packages.txt | grep python
Although you can use grep directly, this is just used as an example.