# 4. 进程通信

![](https://824295091-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MEmUhsvIFBb8ar2-Um3%2F-MEwx040WS26YO1CNfFH%2F-MEwxJjVGgqQ-j2uRkBN%2F%E8%BF%9B%E7%A8%8B%E9%80%9A%E4%BF%A1.svg?alt=media\&token=e015981d-12da-47b9-b2e1-3c0c9c3b8682)

## 1. 进程通信定义

进程通信就是进程之间的信息交换

进程是分配系统资源的单位（包括内存地址空间），因此**各进程**拥有的**内存地址空间相互独立**

为了保证安全，一个进程不能直接访问另一个进程的地址空间。但是进程之间的信息交换又是必须实现的。为了保证进程间的通信安全，操作系统提供了一些方法。

* 共享存储
* 消息传递
* 管道通信

## 2. 共享存储

![](https://824295091-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MEmUhsvIFBb8ar2-Um3%2F-MEwnqDknuT6paBTRVsv%2F-MEwo2bg6nTuHO0hLB6R%2Fimage.png?alt=media\&token=c55452f5-d458-4c65-befa-c72d070cc9ce)

两个进程对共享空间的**访问**必须是**互斥**的（互斥访问通过操作系统提供的工具实现）

**基于数据结构的共享：**&#x6BD4;如共享空间里只能放一个长度为 10 的数组。这种共享方式速度慢、限制多，是一种**低级通信**方式

**基于存储区的共享：**&#x5728;内存中画出一块共享存储区，数据的形式、存放位置都是由进程控制，而不是操作系统。相比之下，这种共享方式速度更快，是一种**高级通信**方式

## 3. 管道通信

![](https://824295091-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MEmUhsvIFBb8ar2-Um3%2F-MEwnqDknuT6paBTRVsv%2F-MEwrSrIo1sjTFRvS4oY%2Fimage.png?alt=media\&token=dafa42be-a7fd-48aa-b4a5-2a67224f2fcb)

1. 管道只能采用**半双工通信**，某一时刻内只能实现单向的传输。如果要实现**双向同时通信**，则需要设置**两个管道**
2. 各进程要**互斥**地访问管道
3. 数据以字符流的形式写入管道，当**管道写满**时，**写进程**的 write() 系统调用将被**阻塞**，等待读进程将数据取走。当读进程将数据全部取走后，**管道变空**，此时**读进程**的 read() 系统调用将被**阻塞**
4. 如果**没写满**，就**不允许读**；如果**没读空**，就**不允许写**
5. 数据一旦被读出，就从管道中被抛弃，这就意味着**读进程最多只能有一个**，否则可能会有读错数据的情况

## 4. 消息传递

进程间的数据交换以**格式化的消息**（Message）为单位。进程通过操作系统提供的“发送消息/接收消息”两个**原语**进行数据交换

消息包括消息头和消息体，其中消息头包括：发送进程 ID、接收进程 ID、消息类型、消息长度等格式化信息

消息传递的两种方式：

* **直接通信方式：**&#x6D88;息直接挂到接收进程的消息缓冲队列上
* **间接通信方式：**&#x6D88;息先发送到中间实体（信箱）中，因此也称“信箱通信方式”。e.g. 计网中的电子邮件系统

![](https://824295091-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MEmUhsvIFBb8ar2-Um3%2F-MEwnqDknuT6paBTRVsv%2F-MEwucKRHVPuBJN-BE-D%2Fimage.png?alt=media\&token=fd48c40c-a292-4f36-985f-ee8d7e68b0f2)





