# Linux 进程间通信

上一篇：[[14 Linux 基本使用补充]]
返回目录：[[Linux 学习指南]]
下一篇：[[16 Linux 内核模块开发]]

> [!info] 来源
> 整理自 [[操作系统课程设计指导书]] 的 4.3～4.5 节。

## 通信方式选择

| 方式 | 特点 | 适用场景 |
| --- | --- | --- |
| 无名管道 | 亲缘进程间的字节流，通常单向 | 父子进程协作、Shell 管道 |
| 有名管道 FIFO | 通过文件系统名字访问 | 无亲缘关系进程的简单通信 |
| 消息队列 | 按消息组织，可按类型接收 | 多生产者/消费者、离散消息 |
| 共享内存 | 多进程映射同一物理内存，速度快 | 大块数据交换；需额外同步 |

## 管道

`pipe(int fd[2])` 创建管道：`fd[0]` 用于读，`fd[1]` 用于写。创建子进程后，应关闭每个进程不使用的一端，否则读端可能因仍有写端打开而无法收到 EOF。

```c
int fd[2];
pipe(fd);
if (fork() == 0) { close(fd[1]); read(fd[0], buf, sizeof buf); }
else { close(fd[0]); write(fd[1], "ok", 2); close(fd[1]); }
```

`mkfifo("/tmp/demo.fifo", 0666)` 创建 FIFO；它仍受文件权限控制，读写双方通常需要配合打开。

## System V 消息队列

基本生命周期：`msgget` 获取/创建队列 -> `msgsnd` 发送 -> `msgrcv` 接收 -> `msgctl(..., IPC_RMID, ...)` 删除。消息通常包含一个正整数类型字段和消息正文；接收者可按类型筛选。程序结束时应清理队列，避免遗留 IPC 对象。

## 共享内存

基本生命周期：`shmget` 分配 -> `shmat` 映射 -> 读写共享区域 -> `shmdt` 解除映射 -> `shmctl(..., IPC_RMID, ...)` 标记删除。共享内存本身不提供互斥、顺序或一致性保证，必须配合信号量、互斥锁等同步机制。
