IPC

进程间通信即 IPC,Inter-Process Communication,讨论的是不同进程之间如何交换数据。

进程是资源分配单位,通常拥有相互独立的地址空间。为了安全,一个进程不能直接读写另一个进程的地址空间。因此,进程通信必须由操作系统提供受控机制。

900

常见 IPC 方式主要有三类:共享存储、消息传递、管道通信

900

共享存储

共享存储让多个进程把同一片物理内存映射到各自地址空间中。这样,进程 P 写入共享区的数据,进程 Q 可以从自己的地址空间中读到。

类型 做法 特点
基于数据结构的共享 共享区只能按系统规定的数据结构使用,例如固定大小数组 限制多,速度相对慢,属于低级通信方式
基于存储区的共享 操作系统划出共享存储区,数据格式和位置由通信进程决定 灵活、速度快,属于高级通信方式

共享存储速度快,但不自动保证访问顺序。多个进程同时读写同一共享区时,需要互斥和同步机制,否则会出现覆盖、读到半成品数据等问题。

共享存储的地址映射细节可联系 Memory-Mapped-Files-And-mmap。这里关注的是 IPC 语义:多个进程通过同一共享区交换数据。

消息传递

消息传递以格式化的消息为单位。进程不直接共享地址空间,而是通过操作系统提供的发送、接收原语交换消息。

一条消息通常包括:

部分 内容
消息头 发送进程 ID、接收进程 ID、消息长度、消息类型等控制信息
消息体 真正要传递的数据

消息传递有两种典型形式:

形式 发送目标 接收来源 特点
直接通信 直接指定接收进程 直接指定发送进程 发送方和接收方需要知道对方身份
间接通信 发送到信箱或消息队列 从信箱或消息队列接收 发送方和接收方通过中间对象解耦

直接通信可以理解为“点名道姓”:进程 P 把消息发给进程 Q,操作系统把消息挂入 Q 的消息队列,Q 再从队列中取走。

间接通信以信箱作为中间实体:多个进程可以向同一信箱发送消息,也可以从同一信箱接收消息。

管道通信

管道是一种特殊共享文件,也可以理解为内核维护的固定大小内存缓冲区。一个进程向管道写数据,另一个进程从管道读数据。

管道的关键规则:

规则 含义
半双工 同一时间段内通常只能单向传输;若要双向通信,需要两个管道
互斥访问 多个进程访问管道时,由操作系统保证必要的互斥
写满阻塞 管道满时,写进程阻塞,直到读进程取走数据
读空阻塞 管道空时,读进程阻塞,直到写进程写入数据
读出即消失 管道中的数据被读出后就不再保留

多个进程读取同一管道时可能发生混乱,因为数据被某个读进程取走后,其他读进程就读不到这部分数据。常见处理方式是限制为多个写进程、一个读进程;也可以由系统安排多个读进程轮流读取。

三种 IPC 对比

方式 数据放在哪里 交换方式 典型特点
共享存储 共享内存区 进程直接读写共享区 速度快,但必须额外处理同步互斥
消息传递 内核消息队列或信箱 通过发送/接收原语传递消息 结构清晰,适合受控通信
管道通信 内核管道缓冲区 一端写,一端读 适合流式数据,读出即消失