操作系统额外内容 - IPC

参考文献

进程间通信方式 IPC

腾讯微信支付 - 实习, 一面.

操作系统课上内容中,我们可以看到课上对进程的内容如下

  • Process Creation
  • Process Termination
  • Process State

往后就是重点的线程内容了。但进程和进程有着很大的区别,比如进程的内存隔离更加严格,一个进程不能直接访问另一个进程的地址空间,也就是说,进程间要进行信息交换就必须通过内核。因此也导致像互斥锁这种简单的通信方案在进程上并不适用。因此需要通过其他方式解决。

管道

管道的本质,就是内核在内存里开辟的一块缓冲区;它对外表现为一个文件,因此进程的读写可以像读写文件一样操作它,但它不属于磁盘上的文件系统,只存在于内存中。

匿名管道 Pipe

该管道通过 pipe() 系统调用创建的管道。它

  1. 只能用于有亲缘关系的进程,如父子进程。
  2. 半双工,因此数据只能向一个方向流动。
  3. 没有名字,数据只存在内存中。其生命周期随着进程结束而消失。

当我们敲 Linux 指令,如 ps | grep "io" 时,其中的 | 就是匿名管道。

有名管道 FIFO

有名管道 FIFO 的名字是由其先进先出的特性决定的。所谓的有名管道,就是提供一个路径名与之关联。这样,任意进程,只要可以访问该路径,就可以通过这个有名管道进行相互通信。

一个有名管道的完整流程如下

首先需要使用 mkfifo 命令创建一个有名管道,然后往里面放数据。

最后结果

可以发现现在该命令行卡住了。此时需要另一个命令行(就是另一个进程)去读取这里的数据。

在新进程读到后,原本的进程也继续执行了

而通过 mkfifo 创建的管道其实就可以当作一份文件实体,该管道会存在于文件系统中,需要通过 rm 删除。

消息队列

消息管道效率仍然较低,不适合频繁交换数据。因此消息传递机制(也就是消息队列)应运而生。进程 A 要给进程 B 发消息,A 进程去消息队列发就可以了,然后 B 进程需要的时候就去消息队列读取。

消息队列的本质是存放在内存中的消息的链表而消息本质上就是用户自定义的数据结构。而且,消息队列也可以实现消息的随即查询,而不一定要先进先出。

消息队列的生命周期随内核而定,只要没有手动释放消息队列,或者没有关闭操作系统,消息队列就会一直存在。

由于消息队列在存入数据和拿出数据时都会发生从用户态到内核态(或反过来)的交换过程,所以在数据量较大时,性能可能不高。

通过系统调用,可以实现消息队列的创建/打开,发送信息,接收,控制/删除这四种操作。

共享内存

共享内存的出现主要是为了避免像消息队列一样频繁拷贝信息的问题。顾名思义,共享内存就是允许不相干的进程将同一段物理内存连接到它们各自的地址空间中,从而使得这些进程可以访问同一个物理内存。如果某个进程向共享内存中写入数据,其所做的改动将立即影响同一片共享内存的任何其他进程。这是最快的一种通信方式。

信号量

本质上是共享内存中的同步与互斥机制,只用于并发控制,其 PV 操作此处不做赘述。

信号 Signal

信号是一种软中断。这是进程通信机制中唯一的异步通信机制,可以在任何时候发送信号给某个进程,从而迫使进程执行信号处理程序。

所有的信号

socket

最通用,最常见的通信方式。此处不赘述。

IO 模型

阻塞式 IO

进程/线程在进行 IO 的整段时间都是被阻塞的。一个 IO 请求会阻塞一条线程,需要额外处理。

非阻塞式 IO

进程把一个套接字设置成非阻塞时,它是在通知内核:如果这个 IO 操作暂时做不了,必须要等,那就别让进程阻塞休眠,而是直接返回错误,告诉进程“现在还不行”,让程序继续运行

应用进程一般会轮询内核,以查看某个操作是否就绪,这么做往往会耗费大量 CPU 时间。

IO复用

IO 复用是 selectpoll 的基础。

我们阻塞于 select 调用,等待数据报套接字变为可读,然后 select 返回套接字可读这一条件,然后调用进程将所读数据报复制到应用缓冲区。

事实上由于使用 select 需要两个系统调用而不是一个,因此该方式还稍有劣势。不过 select 的优势在于我们可以等待多个描述符就绪。

信号驱动 IO

当进程发起一个 IO 时,会向内核注册一个信号处理函数,然后进程返回不阻塞。

当内核数据就绪时会发送一个信号给进程,进程便在信号处理函数中调用 IO 读取数据。

异步 IO

告诉内核启动某个操作,并让内核在整个操作完成后通知我们。这种模型和信号驱动 IO 的区别在于,前者由内核通知我们 IO 操作何时完成(数据已经放好了,直接用就行),后者由内核通知我们何时启动一个 IO 操作(数据好了,自己来读吧)。这种模型和非阻塞式 IO 的区别在于,前者有就绪后通知的机制,后者因为没有通知机制,因此需要进程不断轮询。


操作系统额外内容 - IPC
https://ivanclf.github.io/2026/03/13/os-ex1/
作者
Ivan Chan
发布于
2026年3月13日
许可协议