# 2.6 进程通信 ## 一、进程通信的概念 ### 1.1 什么是进程通信 **进程通信(Inter-Process Communication, IPC)** 是指进程之间的信息交换。 ### 1.2 进程通信的类型 根据通信方式的不同,进程通信分为: - **低级通信**:只能传递状态和整数值(如信号量) - **高级通信**:可以传递大量数据 ### 1.3 进程通信的方式 1. **共享存储器系统** 2. **消息传递系统** 3. **管道通信系统** 4. **客户机-服务器系统** --- ## 二、共享存储器系统 ### 2.1 基本原理 通信的进程通过共享存储区进行通信。 **特点**: - 通信的进程共享一块存储区域 - 进程通过读写共享存储区来交换信息 - 需要同步机制保证互斥访问 ### 2.2 实现方式 #### 基于共享数据结构的通信 **特点**: - 共享某些数据结构 - 如生产者-消费者问题中的缓冲区 - 通信效率低,适合少量数据交换 #### 基于共享存储区的通信 **特点**: - 在内存中分配一块共享存储区 - 进程可以将数据写入共享存储区 - 其他进程可以从共享存储区读取数据 - 需要同步机制(信号量或互斥锁) ### 2.3 优缺点 **优点**: - 通信效率高 - 不需要数据拷贝 **缺点**: - 需要解决同步问题 - 进程必须在同一台计算机上 --- ## 三、消息传递系统 ### 3.1 基本原理 进程通过发送和接收消息来通信。 **特点**: - 进程之间通过消息进行通信 - 不需要共享存储区 - 可以实现分布式通信 ### 3.2 消息格式 ``` 消息头 + 消息正文 ``` **消息头包含**: - 发送进程标识符 - 接收进程标识符 - 消息长度 - 消息类型 - 消息编号 ### 3.3 通信方式 #### 直接通信 **定义**:发送进程直接将消息发送给接收进程。 **原语**: ```c Send(P, message); // 发送消息给进程P Receive(Q, message); // 从进程Q接收消息 ``` **特点**: - 通信链路自动建立 - 一条链路只连接两个进程 - 每对进程之间只有一条链路 #### 间接通信(信箱通信) **定义**:消息发送到信箱,接收进程从信箱取消息。 **原语**: ```c Send(A, message); // 发送消息到信箱A Receive(A, message); // 从信箱A接收消息 ``` **信箱类型**: - **私用信箱**:用户进程建立,拥有者读,其他人写 - **公用信箱**:操作系统建立,所有进程可读写 - **共享信箱**:多个进程共享 **特点**: - 通信链路通过信箱建立 - 一条链路可以连接多个进程 - 每对进程可以有多个链路 ### 3.4 消息缓冲队列 **实现方式**: - 系统维护一个消息缓冲池 - 发送进程申请缓冲区,复制消息,插入接收进程的消息队列 - 接收进程从消息队列取出消息,释放缓冲区 --- ## 四、管道通信系统 ### 4.1 管道的概念 **管道(Pipe)**:连接两个进程的共享文件,用于进程间通信。 **特点**: - 单向通信(一端写,一端读) - 基于文件系统实现 - 遵循先进先出原则 ### 4.2 管道的类型 #### 匿名管道 **特点**: - 用于父子进程或兄弟进程间通信 - 没有名字,只能用于有亲缘关系的进程 - 半双工通信 **创建**: ```c int pipe(int fd[2]); // fd[0]用于读,fd[1]用于写 ``` #### 命名管道(FIFO) **特点**: - 有名字,可用于无亲缘关系的进程 - 以文件形式存在于文件系统中 - 半双工通信 **创建**: ```c int mkfifo(const char *pathname, mode_t mode); ``` ### 4.3 管道的读写规则 - 写满时写进程阻塞,等待读进程读走数据 - 空时读进程阻塞,等待写进程写入数据 - 写端关闭时,读进程读完数据后返回0 - 读端关闭时,写进程收到SIGPIPE信号 --- ## 五、客户机-服务器系统 ### 5.1 套接字(Socket) **定义**:通信的端点,用于网络通信。 **特点**: - 可用于同一台机器或不同机器 - 支持TCP和UDP协议 - 支持双向通信 **类型**: - **流套接字(SOCK_STREAM)**:基于TCP,可靠、面向连接 - **数据报套接字(SOCK_DGRAM)**:基于UDP,不可靠、无连接 ### 5.2 远程过程调用(RPC) **定义**:允许程序调用另一个地址空间的过程或函数。 **特点**: - 使分布式调用看起来像本地调用 - 隐藏底层通信细节 - 需要Stub(存根)程序 **执行过程**: 1. 客户进程以本地方式调用客户Stub 2. 客户Stub打包参数,发送消息给服务器 3. 服务器Stub解包参数,调用服务器过程 4. 服务器执行,返回结果给服务器Stub 5. 服务器Stub打包结果,发送给客户 6. 客户Stub解包结果,返回给客户进程 ### 5.3 远程方法调用(RMI) **定义**:Java中的RPC实现,用于分布式对象通信。 --- ## 六、进程通信的比较 | 通信方式 | 数据量 | 方向 | 适用范围 | 速度 | |---------|--------|------|---------|------| | 共享存储 | 大 | 双向 | 同一机器 | 快 | | 消息传递 | 中 | 双向 | 任意 | 中 | | 管道 | 中 | 单向 | 同一机器 | 中 | | 套接字 | 大 | 双向 | 任意 | 中 | | RPC | 中 | 双向 | 任意 | 慢 | --- ## 七、考研重点 1. **进程通信的类型**:低级通信和高级通信 2. **共享存储器系统**:共享数据结构、共享存储区 3. **消息传递系统**:直接通信、间接通信(信箱) 4. **管道通信**:匿名管道、命名管道 5. **客户机-服务器系统**:套接字、RPC 6. **各种通信方式的优缺点** --- *下一节:2.7 死锁*