Linux 命名管道(FIFO)通信:原理与跨进程实现实战
在 Linux 进程间通信(IPC)中,管道是最基础的方式之一。但常用的匿名管道有一个局限——它只能用于有血缘关系的进程(如父子进程)。如果需要让两个毫无关联的独立进程进行通信,就需要用到命名管道(FIFO)。
命名管道通过文件系统作为媒介,给管道赋予了一个文件名,使得任意进程只要知道路径就能交互。下面我们从原理、创建方式到代码实操,完整梳理这一机制。
一、命名管道(FIFO)是什么?
1. 本质与特点
命名管道和匿名管道的核心逻辑一致,都是基于内核缓冲区的字节流半双工通信。区别在于:命名管道有一个可见的文件系统入口。
这个文件只是一个标识,不存储实际数据(数据仍在内存缓冲区中)。只要知道 FIFO 文件的路径,任意进程都能打开它获取读写描述符。
主要特点包括:
- 跨进程通信:无血缘关系进程也能通信。
- 半双工:数据单向流动,双向需两个 FIFO。
- 阻塞特性:默认读端阻塞直到有写端,反之亦然(可设非阻塞)。
- 生命周期:文件不会随进程退出自动删除,需手动清理。
2. 与匿名管道对比
| 维度 | 匿名管道 (pipe) | 命名管道 (FIFO) |
|---|---|---|
| 通信范围 | 有血缘关系进程 | 任意进程 |
| 标识方式 | 无文件,靠 FD 继承 | 有文件系统入口 |
| 创建方式 | pipe() 系统调用 | mkfifo() 或命令 |
| 生命周期 | 进程退出销毁 | 文件删除才销毁 |
二、命名管道的创建方式
1. 命令行创建
适合快速测试,使用 mkfifo 命令:
# 创建名为 myfifo 的管道
mkfifo myfifo
# 查看文件类型(p 开头表示 pipe)
ls -l myfifo
你会发现该文件大小始终不变,验证了它不是普通文件,而是特殊设备文件。
2. 代码创建
在 C/C++ 中使用 mkfifo() 系统调用:
#include <stdio.h>
#include
{
ret = (FIFO_PATH, );
(ret == ) {
(errno != EEXIST) {
();
;
}
();
} {
();
}
;
}


