Linux 进程间通信进阶
1. 准备阶段:进程间通信的概念
1.1 本质前提
进程间通信(IPC)指的是两个或多个进程进行信息相互传递的过程。我们知道进程具有独立性,一个进程想把自己的数据发送给另一个进程,在默认情况下是比较困难的。
虽然父进程的全局变量子进程可以看到,但这不算严格的进程间通信:
- 只能单向(父到子),不是相互的。
- 不能持续,后续更改后子进程无法感知。
核心原则:一个进程挂掉不会影响另外的进程,即使是父子进程也一样。
要让不同的进程看到同一份资源,操作系统必然要提供系统调用。
1.2 为什么需要 IPC
- 数据传输:一个进程需要将数据发送给另一个进程。
- 资源共享:多个进程之间共享同样的资源。
- 通知事件:一个进程向另一个或一组进程发送消息,通知发生了某种事件。
- 进程控制:某些进程希望完全控制另一个进程的执行(如调试进程)。
1.3 怎么办
进程间通信的本质前提是:先让不同的进程看到同一份资源!后续大部分时候都是想办法建立这种共享资源的访问路径。
2. 进程间通信标准与发展
相对于网络标准,系统标准的发展过程较为漫长。System V 是进程间通信的一个重要定制标准,定义了共享内存、消息队列、信号量等机制的使用规范。
3. 管道的特点和情况总结
3.1 五种特点
- 单向性:设计之初只允许单项数据通信,基于文件实现。
- 血缘关系:通常用于具有血缘关系的进程(如父子进程)之间。
- 生命周期:管道本质是文件,打开它的进程退出,文件也会被系统自动关闭。
- 同步机制:管道内部实现了进程间的同步。
- 字节流:面向字节流,读写次数可能不匹配。
3.2 常见场景
- 写端慢读端快:以慢节奏为准,读端等待。
- 写端快读端慢:读端一次性读取所有数据。
- 写端关闭:读端会收到 EOF。
- 读端关闭:写端继续写入可能会收到 SIGPIPE。
4. 进程池
4.1 常见问题与修复
在实现进程池时,常遇到僵尸进程问题。如果只退出了一个子进程而没有回收所有子进程,会导致资源泄漏。
修复方案:确保在主进程中遍历所有子进程并调用 wait() 回收,同时正确关闭写端文件描述符。
4.2 示例:创建 10 个子进程
通过循环创建子进程,每个子进程处理特定任务,主进程负责管理生命周期。
5. 命名管道(FIFO)
5.1 基本原理
命名管道允许毫不相干的两个进程之间进行通信。客户端不需要建立管道,只需打开已存在的 FIFO 文件。
5.2 关键细节
- 阻塞行为:首次打开时,读端会在
open阻塞,直到有写端打开;反之亦然。这实现了读写同步。 - 字符串处理:不需要像 C 语言那样手动添加
\0,使用std::string或write指定长度即可。 - 权限设置:创建时需指定权限(如 )。


