在 Linux 进程间通信(IPC)中,管道是最基础的方式之一。但平时接触的'匿名管道'有个致命缺陷——只能用于有血缘关系的进程(如父子进程),无法实现无关联进程间的通信。
而**命名管道(简称 FIFO)**正是为解决这个问题而生。它给管道赋予了一个'文件名',通过文件系统作为媒介,让任意两个进程(无论是否有血缘关系)都能通过这个'命名'实现数据交互。
一、先搞懂:命名管道(FIFO)是什么?
1. 命名管道的本质
命名管道和匿名管道的核心通信逻辑完全一致——都是基于'字节流'的半双工通信(同一时刻只能单向传输数据),底层都是内核中的缓冲区。
两者的核心区别在于:命名管道有一个可见的文件系统入口(一个以.fifo 为后缀的文件),这个文件只是一个'标识',不存储实际数据(数据仍在内存缓冲区中);而匿名管道没有文件入口,只能通过父子进程继承文件描述符来通信。
简单来说:匿名管道是'隐式的、血缘专属',命名管道是'显式的、通用的',只要知道 FIFO 文件的路径,任意进程都能与之通信。
2. 命名管道的核心特点
- 跨进程通信:无血缘关系的进程(如两个独立的程序),只要知道 FIFO 文件路径,就能通过它通信;
- 半双工通信:数据只能单向流动,若要实现双向通信,需要创建两个 FIFO(一个用于 A→B,一个用于 B→A);
- 基于文件标识:FIFO 文件存在于文件系统中,进程通过打开这个文件,获取读写文件描述符,进而实现通信;
- 阻塞特性:默认情况下,打开 FIFO 的读端会阻塞,直到有进程打开写端;打开写端也会阻塞,直到有进程打开读端(可通过 O_NONBLOCK 设置为非阻塞);
- 生命周期:FIFO 文件不会随进程退出而自动删除,需要手动删除(rm 命令或 unlink 函数),否则会一直存在于文件系统中。

3. 命名管道与匿名管道的对比
为了更清晰区分,做一个简单对比表,避免混淆:
| 对比维度 | 匿名管道(pipe) | 命名管道(FIFO) |
|---|---|---|
| 通信范围 | 有血缘关系的进程(父子、兄弟) | 任意进程(无血缘关系也可) |
| 标识方式 | 无文件标识,通过文件描述符继承 | 有文件系统入口(FIFO 文件) |
| 创建方式 | 通过 pipe() 系统调用创建 | 通过 mkfifo() 系统调用或 mkfifo 命令创建 |
| 生命周期 | 随进程退出而销毁(文件描述符关闭) | 随 FIFO 文件删除而销毁,进程退出不影响文件 |
| 使用场景 | 父子进程间简单通信(如 shell 管道) | 无关联进程间通信(如两个独立程序交互) |


