One way in which processes with private virtual address spaces can communicate is through message passing — by sending and receiving messages to each other. Message passing allows programs to exchange arbitrary data rather than just a small set of predefined messages like those supported by signals. And operating systems typically implement a few different types of message passing abstractions that processes can use to communicate.
The message passing interprocess communication model consists of three parts:
Processes allocate some type of message channel from the OS. Example message channel types include pipes for one-way communication, and sockets for two-way communication. There may be additional connection setup steps that processes need to take to configure the message channel.
Processes use the message channel to send and receive messages to each other.
Processes close their end of the message channel when they are done using it.
A pipe is a one-way communication channel for two processes running on the same machine. One-way means that one end of the pipe is for sending messages (or writing to) only, and the other end of the pipe is for receiving messages (or for reading from) only. Pipes are commonly used in shell commands to send the output from one process to the input of another process.
For example, consider the following command entered at a bash shell prompt
that creates a pipe between two processes (the
cat process outputs the
contents of file
foo.c and the pipe (
|) redirects that output to the input
grep command that searches for the string "factorial" in
$ cat foo.c | grep factorial
To execute this command, the bash shell process calls the
pipe system call to
request that the OS creates a pipe communication. The pipe will be used by the
shell’s two child processes (
grep). The shell program sets
stdout to write to the write end of the pipe and
stdin to read from the read end of the pipe, so that
when the child processes are created and run, the
cat process’s output
will be sent as input to the
grep process (see Figure 1).
While pipes transmit data from one process to another in only one direction, other message passing abstractions allow processes to communicate in both directions. A socket is a two-way communication channel, which means that each end of a socket can be used for both sending and receiving messages. Sockets can be used by communicating processes running on the same computer or running on different computers connected by a network (see Figure 2). The computers could be connected by a local area network (LAN), which connects computers in a small area, such as a network in a university computer science department. The communicating processes could also be on different LANs, connected to the Internet. As long as there exists some path through network connections between the two machines, the processes can use sockets to communicate.
Because each individual computer is its own system (hardware and OS), and
because the OS on one system does not know about or manage resources on the other
system, message passing is the only way in which processes on different
computers can communicate. To support this type of communication,
operating systems need to implement a common message passing protocol for
sending and receiving messages over a network. TCP/IP is one example of
a messaging protocol that can be used to send messages over the
Internet. When a process wants to send a message to another,
it makes a
send system call, passing the OS a socket
on which it wants to transmit, the message buffer, and possibly additional
information about the message or its intended recipient.
The OS takes care of packing up the message in the message buffer, and
sending it out over the network to the other machine. When an OS receives
a message from the network, it unpacks the message and delivers it to
the process on its system that has requested to receive the message.
This process may be in a Blocked state waiting for the message to arrive.
In this case, receipt of the message makes the process Ready to run again.
There are many system software abstractions built on top of message passing that hide the message passing details from the programmer. However, any communication between processes on different computers must use message passing at the lowest levels (communicating through shared memory or signals is not an option for processes running on different systems). In the Parallel Systems Chapter, we discuss message passing and the abstractions built atop it in more detail.