﻿---
title: Inter Process Communication
date: 2024-03-11
excerpt: "Types of IPC: shared memory, pipes, message-passing systems, mailboxes, and client-server mechanisms like sockets and RPC."
tags: [OS, Process]
thumbnail: https://assets.vluv.space/cover/OS/Ch2-3IoC.webp
cover: https://assets.vluv.space/cover/OS/Ch2-3IoC.webp
updated: 2026-07-08 21:17:39
lang: en
i18n:
  cn: /Ch2-3InterprocessCommunication
  translation: 2
---

<script type="module" src="/js/components/tab.js"></script>

## Types Of IPC

### Overview

**Low-level communication**: mutual exclusion and synchronization between processes are classified as low-level communication because the amount of information exchanged is small.
The semaphore mechanism works well as a synchronization tool, but as a communication tool it falls short, mainly in two respects:

1. Low efficiency: the producer can only deposit one product (message) into the buffer pool at a time, and the consumer can only take one message from the buffer at a time;
2. The communication is not transparent to the user.

---

**High-level communication**: a communication style in which users can directly use a set of communication commands provided by the operating system to transfer large amounts of data efficiently. Common high-level communication mechanisms include:

- **Shared-memory system**: a region of memory is allocated as a shared storage area
- **Pipe communication**: the writer writes data into a pipe file; the reader reads data from that file
- **Message-passing system**: data is exchanged between processes in units of messages
  - Direct communication
  - Indirect communication
- **Client-server system**

### Shared-Memory System

1. **Communication based on shared data structures**
   Processes share certain data structures and exchange information through them.
   In the producer-consumer problem, for example, communication is implemented with the bounded-buffer data structure. This style is inefficient and only suitable for transferring relatively small amounts of data.

2. **Communication based on a shared storage area**
   The operating system carves out a region of memory as a shared storage area.
   Before communicating, a process requests a partition of the shared storage area from the operating system.
   The requesting process then attaches the obtained shared partition to itself, after which it can read and write the shared partition just like ordinary memory.
   Under this scheme, synchronization and mutually exclusive access to the shared storage area are the processes' own responsibility.

### Pipe Communication

A "pipe" is a shared file, also called a pipe file, that connects a reading process and a writing process to enable communication between them.
The sending process (Writer) that feeds the pipe (shared file) writes large amounts of data into it as a **character stream**;
the receiving process (Reader) that consumes the pipe's output reads data from it. Since the sender and receiver communicate through the pipe, this is called pipe communication.
This mechanism originated in UNIX; because it transfers large amounts of data effectively, it has been adopted by many other operating systems.

To coordinate both sides of the communication, the pipe mechanism must provide **three** kinds of coordination:

- **Mutual exclusion**: while one process is reading from or writing to the pipe, the other process must wait.
- **Synchronization**: when the writing (input) process has written a certain amount of data (say 4KB) into the pipe, it goes to sleep and waits until the reading (output) process takes the data away and wakes it up. Likewise, when the reading process finds the pipe empty, it should sleep and wait until the writing process writes data into the pipe and wakes it up.
- **Determining whether the other party exists**: communication can proceed only after confirming that the other party exists.

Linux named pipes are well suited to passing data between two processes on the same machine. A named pipe also takes the form of a file, but reads and writes follow the FIFO principle.

```c
#define FIFO_NAME "/tmp/my_fifo"
#define BUFFER_SIZE PIPE_BUF
mkfifo(FIFO_NAME,0777);
```

### Message-Passing System

The most widely used interprocess communication mechanism: data is exchanged between processes in units of formatted messages.
Programmers use communication primitives to communicate; the implementation details are hidden, which simplifies writing communication programs.
Communication between the microkernel and server programs uses this mechanism, and it can meet the communication requirements of multiprocessor OSes, distributed OSes, and computer networks.

**Implementation approaches for message-passing communication**

- **Direct communication** `send(),receive()`
- **Indirect communication** — mailboxes

#### Direct Communication

The sending process uses a send command provided by the OS to deliver a message directly to the target process. The system typically provides two types of communication commands (primitives):

- **Symmetric Addressing**
  `Send(Receiver, Message);`
  `Receive(Sender, Message);`
  For example, the primitive `Send(P2, m1)` sends message m1 to the receiving process P2, while the primitive `Receive(P1，m1)` receives message m1 sent by P1.
- **Asymmetric Addressing**
  `Send(P, Message);` sends a message to the receiving process P;
  `Receive(id,Message);` receives a message from any process; the process id is not fixed.

Using direct communication primitives to solve the producer-consumer problem:
after the producer produces a product (message), it uses the Send primitive to send the message to the consumer process; the consumer process uses the Receive primitive to obtain a message. If no message has been produced yet, the consumer must wait until the producer sends one over.

```pascal
repeat
     …
    produce an item in nextp;
      …
    send(consumer, nextp);
   until false;

repeat
    receive(producer, nextc);
      …
    consume the item in nextc;
  until false;
```

**Message buffer queue communication mechanism**

The sending process uses the `send` primitive to deliver a message directly to the receiving process's message buffer queue;
the receiving process uses the `receive` primitive to receive the message;
this is used for local interprocess communication.

![](https://assets.vluv.space/UESTC/OS/Ch2-3IPC/Ch2-3InterprocessCommunication-2024-03-11-13-21-04.webp)

**Send**

- Before invoking the send primitive, the **sending process** sets up a send area `a` in its own memory space, filling in the message body, the sender's identifier, the message length, and other information, then calls the send primitive to deliver the message to the target (receiving) process.
- The send primitive first requests a buffer `i` based on the message length `a.size` set in the send area `a`, then copies the information from send area `a` into buffer `i`. To hang `i` on the **receiving process's message queue** `mq`, it must first obtain the **receiving process's** internal identifier `j`, then attach `i` to `j.mq`.
- Since this queue is a critical resource, `wait` and `signal` operations must be executed before and after the `insert` operation.

**Receive**

- The **receiving process** calls the receive primitive `receive(b)`, removes the first message buffer i from its own message queue `mq`, and copies its data into the designated message receiving area starting at address b.
- After receiving the message, the receiving process returns to user mode and continues.

![](https://assets.vluv.space/UESTC/OS/Ch2-3IPC/Ch2-3InterprocessCommunication-2024-03-11-13-24-54.webp)

#### Issues in Implementing Message-Passing Systems

- **Communication link**
  For a sending process and a receiving process to communicate, a communication link must be established between them. There are two ways to establish one.
  - First: before communicating, the sending process uses an explicit "establish connection" command (primitive) to ask the system to set up a communication link, and uses an explicit command to tear it down when done. This approach is mainly used in computer networks.
  - Second: the sending process does not need to explicitly request a link; it simply uses the send command (primitive) provided by the system, and the system automatically establishes a link. This approach is mainly used in single-machine systems.

  By **connection method**, communication links fall into two categories:
  - **Point-to-point links**, where one link connects exactly two nodes (processes);
  - **Multipoint links**, where one link connects multiple (n > 2) nodes (processes).
    By **communication direction**, links fall into two kinds:
  - **Unidirectional links**, which only allow the sender to send messages to the receiver;
  - **Bidirectional links**, which allow process A to send messages to process B and process B to send messages to process A at the same time.

- **Message format**
  - **Fixed-length messages**
    Some OSes use a relatively short fixed-length message format, which reduces the overhead of processing and storing messages.
  - **Variable-length messages**
    Other OSes use a variable-length message format, meaning the length of a message a process sends can vary. The system pays more overhead in processing and storing variable-length messages, but it is more convenient for users.
    Note: each format has its pros and cons, so many systems (including computer networks) use both.
- **Process synchronization**
  When processes communicate through a message queue, they need to synchronize. There are three synchronization modes:
  - **Both sender and receiver block**: rendezvous synchronization; messages are passed when available, and both block when there are none.
  - **Sender does not block, receiver blocks**: the sender sends messages as fast as possible; the receiver normally blocks and is only woken when a message arrives, for example multiple users sharing one print service.
  - **Neither sender nor receiver blocks**: both are busy with their own work and only block when they cannot proceed, for example when the sender and receiver are connected by a message queue of length n.

#### Indirect Communication

A mailbox is one implementation of indirect communication: a special message queue used for interprocess communication.

**Creating and removing mailboxes**: a process can use the mailbox-creation primitive to create a new mailbox. The creator must give the mailbox's name and attributes (public, private, or shared); for a shared mailbox, the names of the sharers must also be given. When a process no longer needs to read the mailbox, it can remove it with the mailbox-removal primitive.
**Sending and receiving messages**: when processes communicate through a mailbox, they must use a shared mailbox and the following communication primitives provided by the system.
`Send(mailbox, message);` sends a message to the specified mailbox;
`Receive(mailbox, message);` receives a message from the specified mailbox;

A mailbox is defined as a data structure. Logically, it can be divided into two parts: the MailboxHeader and the MailboxBody.

![](https://assets.vluv.space/UESTC/OS/Ch2-3IPC/Ch2-3InterprocessCommunication-2024-03-11-14-00-40.webp)

A mailbox may be created by the operating system or by a user process; the creator is the mailbox's owner. Accordingly, mailboxes fall into three categories:

- **Private mailbox** A user **process** can create a new mailbox for itself as part of the process. The mailbox's owner has the right to read messages from it; other users can only send messages they compose into it. A private mailbox can be implemented with a unidirectional communication link. When the owning process terminates, the mailbox disappears with it.
- **Public mailbox** Created by the **operating system** and made available to all authorized processes in the system. A process can both send messages to the mailbox and read messages addressed to itself from it. Clearly, a public mailbox should be implemented with a bidirectional communication link. A public mailbox usually exists for the entire time the system is running.
- **Shared mailbox** Created by some **process**, marked as shareable at or after creation, with the names of the sharing processes (users) specified. Both the owner and the sharers have the right to take messages addressed to themselves from the mailbox.

When communicating through mailboxes, four kinds of relationships exist between senders and receivers:

- **One-to-one** A dedicated communication link can be established between the sender and receiver so their interaction is free from interference by other processes.
- **Many-to-one** Allows a serving process to interact with multiple user processes; also called client/server interaction.
- **One-to-many** Allows one sender to interact with multiple receivers, so the sender can broadcast messages to multiple receivers.
- **Many-to-many** Allows a public mailbox to be established so that multiple processes can deposit messages into it, and each can take out the messages addressed to itself.

### Client-Server System

#### Socket

**Socket definition**
Windows Sockets is **a standard network interface provided to upper-layer applications**, mainly for data communication over a network. Upper-layer applications need not care about Winsock's implementation details; it provides transparent services to them.
The Windows Sockets specification defines a network programming interface for Microsoft Windows, modeled on the Socket interface popularized in BSD UNIX at U.C. Berkeley.
It includes not only the familiar Berkeley Socket style library functions, but also a set of Windows-specific extension functions that let programmers take full advantage of the Windows message-driven mechanism.

<center>

<img src="https://assets.vluv.space/UESTC/OS/Ch2-3IPC/Ch2-3InterprocessCommunication-2024-03-11-14-18-48.webp" style="width:50%;" />

</center>

**TCP/IP**

The core of the TCP/IP protocol suite consists of the transport-layer protocols (TCP, UDP), the network-layer protocol (IP), and the physical interface layer; these three layers are usually implemented in the operating system kernel, so users generally do not touch them.
When programming, the interface comes in two forms: system calls provided directly by the kernel, and functions provided as library functions. The former are implemented inside the kernel, the latter outside it. User services must go through applications outside the kernel, so sockets are used to implement them.

**The relationship between TCP/IP and WinSock**

WinSock is not a network protocol; it is just a network programming interface, which can be viewed as a wrapper around certain protocols.
WinSock is a wrapper around TCP/IP: you can invoke TCP/IP's various capabilities by calling WinSock's interface functions.
For example, to send data over TCP/IP, you can use WinSock's Send() interface function to invoke TCP/IP's data-sending capability; how the data is actually sent is something WinSock has already wrapped up for you.

<x-tabs>

<x-tab title="TCP" active>

![TCP](https://assets.vluv.space/UESTC/OS/Ch2-3IPC/Ch2-3InterprocessCommunication-2024-03-11-14-20-43.webp)

</x-tab>

<x-tab title="UDP">

![UDP](https://assets.vluv.space/UESTC/OS/Ch2-3IPC/Ch2-3InterprocessCommunication-2024-03-11-14-28-31.webp)

  </x-tab>

</x-tabs>

#### Remote Procedure Call (RPC)

**Remote Procedure Call (RPC)** is a communication protocol for systems connected by a network. The protocol allows a process running on one (local) host to invoke a process on another (remote) host, while appearing to the programmer as an ordinary procedure call, with no extra programming required. If the software involved is object-oriented, a remote procedure call may also be called a remote method invocation.
RPC mainly solves two problems:

- Calling between services in a distributed system.
- Making remote calls as convenient as local calls, so the caller does not perceive the remote-call logic.

**Steps**

1. Call the client stub; pass the parameters
2. Call the local kernel to send a network message
3. The message is transmitted to the remote host
4. The server stub gets the message and extracts the parameters
5. Execute the remote procedure
6. The executed procedure returns the result to the server stub
7. The server stub packages the result and calls the remote kernel
8. The message is transmitted back to the local host
9. The client stub receives the message from the kernel
10. The client receives the data returned by the stub

![Ch2-3InterprocessCommunication-2024-03-11-14-51-43](https://assets.vluv.space/UESTC/OS/Ch2-3IPC/Ch2-3InterprocessCommunication-2024-03-11-14-51-43.webp)
