Introduction
Processes are isolated by design: each has its own address space, and one cannot read another's variables. Yet many tasks need cooperating processes: a shell pipeline passes output from one program to the next, a database server answers queries from clients, a browser splits work among several processes. Inter-process communication (IPC) is the set of mechanisms the OS provides for such processes to exchange data and coordinate.
There are two fundamental models. In shared memory, the kernel maps the same physical memory into two address spaces, and the processes then read and write it directly. In message passing, processes call send and receive, and the kernel carries the data. Pipes, message queues, sockets and signals are all forms of message passing. The choice trades speed against simplicity and safety.
Prerequisites
- Processes, PCB and Process States: address spaces, blocking and waiting states.
- Process Creation and fork(): file descriptors are inherited across
fork, which is how pipes reach a child.
Core concepts
The two models
| Aspect | Shared memory | Message passing |
|---|---|---|
| Setup | System calls to create and attach a region (shm_open plus mmap, or shmget plus shmat) | A channel: pipe, queue, socket, or none for direct addressing |
| Per transfer | Ordinary loads and stores; no kernel involvement | One system call to send and one to receive |
| Copies per transfer | None beyond the write itself | Typically two: sender to kernel, kernel to receiver |
| Synchronization | Programmer's job (semaphores, mutexes) | Built in: receive blocks until data arrives |
| Best for | Large or frequent data between processes on one machine | Small messages, distributed systems, simpler correctness |
Shared memory is faster, message passing is safer. Once set up, shared memory costs nothing per access, but conflicting accesses with at least one writer need suitable synchronization and memory ordering; read-only or disjoint access need not be locked. Message passing pays a system call and a copy per message but cannot corrupt the other side's memory.

Message-passing design choices
- Naming. Direct:
send(P, msg),receive(Q, msg); a link connects exactly one pair. Indirect: messages go to a mailbox (port); several processes may share one mailbox, and a pair may share several. - Synchronization. A blocking send waits until the message is received (or accepted by the mailbox); a non-blocking send returns at once. A blocking receive waits until a message is available; a non-blocking receive returns a message or "none". Blocking send plus blocking receive is a rendezvous.
- Buffering. The link's queue has zero capacity (sender must block until the receiver takes the message, so it is a rendezvous), bounded capacity (sender blocks only when the queue is full), or unbounded capacity (sender never blocks).
Pipes
An ordinary (anonymous) pipe is a one-way byte stream with a read end and a write end, created by pipe(fd): fd[0] is for reading and fd[1] for writing. It exists only while some process holds it open, and it is typically shared by related processes through inherited descriptors, usually a parent and child after fork. Unrelated processes need another way to obtain a descriptor, such as descriptor passing. Two-way communication needs two pipes.
int fd[2]; char buf[16];
pipe(fd);
if (fork() == 0) { /* child: reader */
close(fd[1]);
ssize_t n = read(fd[0], buf, sizeof buf); /* blocks until data or EOF */
/* n == 5 and buf starts with "hello" */
_exit(0);
}
close(fd[0]); /* parent: writer */
write(fd[1], "hello", 5);
close(fd[1]); /* reader then sees end-of-file */
wait(NULL);Pipe rules worth knowing: read on an empty pipe blocks while some writer still has it open, and returns 0 (end of file) once all write ends are closed; write on a full pipe blocks; writing to a pipe with no reader raises the signal SIGPIPE. A process must close the ends it does not use, or the reader never sees end of file.
A named pipe (FIFO, created by mkfifo) has a name in the file system, outlives its creator and can connect unrelated processes on one machine.
Other mechanisms
- Message queues: kernel-held lists of typed messages (System V
msgsndandmsgrcv, POSIXmq_send). - Sockets: endpoints identified by an address and port; they work between machines. See Socket API.
- Signals: ordinary/basic numbered asynchronous notifications (for example
SIGINT,SIGKILL,SIGCHLD); a handler runs or a default action (often termination) happens. Queued real-time/POSIX signals may carry a small value. - Remote procedure call (RPC): makes a message exchange look like a function call; parameters are marshalled into a message.
Worked examples
Bounded buffer capacity
With and the in/out scheme, a producer that runs alone fills slots 0 to 6 and then spins: 7 items, in , out , and out, so the buffer reports full. After the consumer removes 3 items, out and the producer can add 3 more, wrapping in round to 2.
Cost of moving 1 MiB
Process A sends 1 MiB (1,048,576 bytes) to process B.
- Message passing with 4 KiB messages: messages, so 256
sendand 256receivecalls, 512 system calls in all, and each byte is copied twice (into and out of the kernel): 2 MiB of copying. - Shared memory: a fixed number of setup calls, after which A writes the data straight into the shared region. No per-message system calls, but A and B must still synchronize (for example one semaphore signal when the data is complete).
Important properties and observations
- Message passing gives synchronization for free (a blocking
receivewaits for data); shared memory gives speed and needs explicit synchronization. - A zero-capacity link forces both sides to meet: the sender blocks until the receiver takes the message.
- An ordinary pipe is unidirectional and is usually shared through inherited descriptors by related processes; unrelated processes can use descriptor passing. A named FIFO can instead be opened by path.
- Shared memory regions persist until removed (System V segments even survive the processes that created them); this is a common source of leaks.
Common misconceptions.
- "Shared memory needs a system call for every access." Only for setup; accesses are ordinary memory operations.
- "A pipe can be read by both ends." A pipe has one read end and one write end.
- "Message passing cannot deadlock." Two processes that each block in
receivewaiting for the other deadlock just as surely.
GATE examination perspective
- Model comparison. Shared memory: fastest, kernel only at setup, explicit synchronization. Message passing: system call per message, kernel copies, built-in blocking.
- Bounded buffer with in and out. At most items; full is , empty is .
- Blocking semantics. Know the four combinations of blocking and non-blocking send and receive; zero capacity implies rendezvous.
- Pipe behaviour. Read blocks on empty while writers exist; read returns 0 when the pipe is empty and all write ends are closed; unidirectional; inherited through
fork. - Counting system calls. Messages times two (send and receive); bytes copied twice.
Summary
Sources
- A. Silberschatz, P. B. Galvin, G. Gagne, Operating System Concepts, 10th ed., Wiley: Chapter 3 (3.4 Interprocess Communication, 3.5 IPC in Shared-Memory Systems, 3.6 IPC in Message-Passing Systems, 3.7 Examples of IPC Systems).
- A. S. Tanenbaum, H. Bos, Modern Operating Systems, 4th ed., Pearson: Section 2.3.8 Message Passing.