实用指南:学习笔记——IPC(进程间通信)
IPC(进程间通信)
一、为什么需要IPC?
进程空间都是独立的(虚拟地址空间隔离)
但进程之间有数据共享或交换需求
需要一种机制让进程间能够通信
二、IPC通信方式分类
1. 古老的通信方式
无名管道(匿名管道)
有名管道(FIFO)
信号(Signal)
注意:管道是自动申请资源并继续运行程序
2. IPC对象通信(System V IPC)
消息队列(用的相对少,不讨论)
共享内存
信号量集
主要用于:System V、BSD、SUSE、Fedora、kernel.org等系统
3. Socket通信
主要用于网络通信
也可用于本地进程间通信
三、管道底层实现
底层数据结构:队列(先进先出)
无名管道(Unnamed Pipe)=>
pipe只能用于有亲缘关系的进程通信(如父子进程)
四、管道特性
1. 工作模式
半双工工作模式
实际编程中,通常当作单工使用
2. 文件特性
所有管道都是特殊文件
不支持定位操作
lseek→ 用于文件描述符fseek→ 用于FILE*
建议使用文件IO:
open,read,write,close可选使用标准IO(带缓冲区):
fgets,fread,fgetc
3. 编程顺序
创建管道 → fork → 读写管道 → 关闭管道
五、管道行为分析
1. 写端行为
读端存在,一直向管道写:
- 超过64K(默认缓冲区大小)→ 写会阻塞
- 原因:写段写的太快
2. 读端行为
写端存在,从管道读:
- 如果管道为空 → 读会阻塞
- 原因:读段读的太快
3. 管道破裂(Broken Pipe)
读端关闭,继续写管道:
- 导致写段进程收到SIGPIPE信号
- 默认行为:进程退出
4. 管道结束
写端关闭,读管道:
- 如果管道没有内容 → read返回0
- 表示:进程间通信结束
六、有名管道(FIFO)
1. 特点
有名管道 =>
fifo可以用于任意单机进程通信
在文件系统中可见(有文件名称)
2. 编程步骤
创建有名管道 → 打开有名管道 → 读写管道 → 关闭管道 → 卸载有名管道
3. 特性
具有无名管道所有特性
额外特性:
如果有一端没有打开
open函数会阻塞直到另一端也打开
七、相关函数
1. pipe函数
int pipe(int pipefd[2]);
功能:创建并打开一个无名管道
参数:
pipefd[0]→ 无名管道的固定读端pipefd[1]→ 无名管道的固定写端
返回值:
成功:0
失败:-1
2. mkfifo函数
int mkfifo(const char *pathname, mode_t mode);
功能:在指定路径下创建有名管道文件
参数:
pathname→ 要创建的有名管道路径+名称mode→ 八进制文件权限(如0666)
返回值:
成功:0
失败:-1
八、使用场景对比
| 特性 | 无名管道 | 有名管道 |
|---|---|---|
| 关系要求 | 必须有亲缘关系 | 任意进程 |
| 文件可见性 | 不可见 | 文件系统可见 |
| 创建方式 | pipe() | mkfifo() |
| 打开阻塞 | 不适用 | open会阻塞 |
| 生命周期 | 随进程结束 | 持久存在直到删除 |
九、注意事项
管道是半双工的,但通常按单工使用
管道不能定位,只能顺序读写
注意处理管道破裂(SIGPIPE信号)
读写阻塞是正常现象,需要合理设计程序逻辑
及时关闭不需要的文件描述符,避免资源泄漏

浙公网安备 33010602011771号