2.1.5 进程间通信

进程拥有各自独立的地址空间,为了协同完成一项工作,它们需要一种“桥梁”把数据与事件在彼此之间安全、高效地传递。常见的做法大致有四类:把一块内存区域共享出来供多个进程直接读写;让进程通过“发送/接收”消息进行互动;用内核维护的“管道缓冲区”串联起数据流;以及用“信号”这种异步通知方式传达事件。下面依次展开,并配以流程示意图,便于将抽象概念与运行时行为对应起来。


2.1.5.1 共享内存

当通信的目标是“大量数据的高效传递”,最直接的方案就是让多个进程看到同一片内存区域。共享内存的优势在于“零拷贝”:数据无需在内核与用户空间来回搬运,生产者写入的内容,消费者在自己的地址空间就能立刻读到。需要注意的是,高效往往伴随风险——由于彼此直接读写同一片区域,读写时序必须“先约法、后协作”,否则很容易出现数据覆盖或读到一半的“脏”内容。

为了把共享内存用得稳妥,通常会把操作分成几个清晰的步骤,并配合同步机制约束访问次序:
(1)创建/获取:一方创建共享区并获得“标识”;其他参与者据此获取同一共享区。
(2)附加/映射:各进程把共享区“挂接”到自己的地址空间,得到可读写的内存起始地址。
(3)读写/同步:生产者写入、消费者读取,但读写之间需要同步(如互斥锁、条件变量或信号量)保证原子性与可见性。
(4)分离/删除:通信结束,各方把共享区从本进程地址空间分离;当不再需要时由创建方删除共享区。

计算机操作系统进程间通信原理_java

要点提示(与图关键词一致):“创建/获取—附加/映射—读写—同步—分离/删除”是共享内存的基本节拍;其中“同步”不可缺位,它决定了数据是否被有序地生产与消费。


2.1.5.2 消息传递

如果把共享内存比作“共用一张桌子”,消息传递更像是“写好便条再递给对方”。进程通过系统提供的“发送/接收”原语进行通信,消息在内核维护的**消息队列/信箱(端口)**中排队,接收方按需取走。这种方式的优点是隔离清晰、边界明确——每条消息都有格式和长度,不同进程不会直接触碰彼此的地址空间;代价是需要内核在收发之间搬运与排队,吞吐上不如共享内存。

在实际使用中,常围绕两个问题进行取舍:其一是寻址方式——直接把消息发给对方,还是发到一个信箱(端口)再由对方领取;其二是阻塞语义——当队列已满或为空时,发送/接收是否阻塞等待,抑或返回一个可重试的结果。无论采用何种变体,核心节拍都离不开“发送—排队—接收”。

计算机操作系统进程间通信原理_前端_02

**要点提示(与图关键词一致):**消息经由“发送”进入“信箱/消息队列”,在其中“排队”,最终被目标进程“接收”。围绕“排队”可选择阻塞或非阻塞策略,以平衡实时性与实现复杂度。


2.1.5.3 管道

当通信呈现稳定的“一端生产、另一端消费”的数据流形态时,“管道”是最顺手的工具。可以把管道理解为内核维护的一段管道缓冲区:写端把数据“写入”,读端从另一头“读取”。匿名管道通常用于有亲缘关系的进程之间(例如父子进程),命名管道(FIFO)则允许无亲缘的进程通过路径名相会。管道天然是字节流,强调顺序到达;也正因如此,它特别适合“串联工具”的场景。

为了把管道的行为说清楚,抓住三个关键点就够了:
(1)方向与缓冲:经典管道是单向的,数据经由“写入”进入管道缓冲区,再被另一端“读取”。
(2)阻塞语义:缓冲区“写满”时写端会阻塞,缓冲区“读空”时读端会阻塞;非阻塞模式下则返回可重试的状态。
(3)端点关闭:当“写端关闭”而读端仍在读取时,将读到“结束标记(EOF)”;当“读端关闭”而写端继续写入时,写端会收到错误以示对端已不存在。

写入

读取

写满

读空

写端关闭

读端关闭

写端进程

管道缓冲区

读端进程

结束标记

写入错误

要点提示(与图关键词一致):写入—管道缓冲区—读取”是主通路;“写满/读空”对应阻塞点;“写端关闭/读端关闭”定义了结束与错误的语义。


2.1.5.4 信号

前面的三种方式主要用于“传数据”,而信号更像“传事件”。当某个重要事件发生时(例如用户按下中断键、定时器到期、子进程退出、进程间显式发送),系统把一个信号编号投递给目标进程。目标进程要么按默认动作处理(如终止、忽略),要么执行预先注册的自定义处理器。与前述同步通信不同,信号是异步的:它可能随时到来,打断当前执行路径,先处理“紧急事务”再返回原处继续。

把信号的生命历程拆开看,更便于理解其运行时行为:
(1)产生:事件触发或进程显式发送,一个特定的信号被“生成”。
(2)投递:内核把该信号“投递”到目标进程,若该信号被“屏蔽”,则暂时处于“挂起”状态。
(3)递达/处理:当信号通过屏蔽检查后“递达”,进程要么执行“默认动作”,要么进入“自定义处理器”;处理完毕后返回原先的执行点。

计算机操作系统进程间通信原理_java_03

要点提示(与图关键词一致):产生—投递—屏蔽/挂起—递达—处理(默认动作/自定义处理器)”给出了信号从出现到落地的完整链条;把握“屏蔽与挂起”的配合,才能解释“为什么信号没有立刻触发处理”的现象。


小结式提醒:四类 IPC 的核心差异在于“数据走哪里、谁在排队、何时阻塞、如何收尾”。共享内存强调直接读写+同步;消息传递强调发送/接收+排队;管道强调字节流+缓冲语义;信号强调异步事件+默认/自定义处理。掌握每个关键词在图中的位置,做题时就能把场景迅速映射到正确的通信机制。