1 命名管道(FIFO)的文件唯一性与进程间通信
命名管道(也称为FIFO)是一种特殊的文件类型,它允许无亲缘关系的进程通过文件系统进行通信。以下是命名管道如何保证不同进程访问同一资源的机制:
文件唯一性保证机制
-
路径名作为全局标识符
-
命名管道在文件系统中有一个唯一的路径名
-
所有进程通过这个路径名访问同一个管道资源
-
例如:
/tmp/my_pipe
对所有进程都指向同一个FIFO
-
-
创建与访问方式
#include <sys/stat.h> int mkfifo(const char *pathname, mode_t mode);
-
第一个创建管道的进程使用
mkfifo()
系统调用 -
后续进程只需使用常规的
open()
函数打开同一路径
-
-
内核维护的单一实例
-
虽然看起来像普通文件,但内核会确保:
-
只有一个管道实例与特定路径名关联
-
所有打开该路径的进程访问的是同一个内核缓冲区
-
-
进程间通信实现前提
-
通信准备阶段
-
进程A创建命名管道:
$ mkfifo /tmp/my_pipe 或 $ mkfifo("/tmp/my_pipe", 0666);
-
进程B通过相同路径打开同一管道
-
-
打开特性
-
只读打开会阻塞,直到另一个进程以写方式打开
-
只写打开会阻塞,直到另一个进程以读方式打开
-
可以使用
O_NONBLOCK
标志非阻塞打开
-
-
通信过程示例
// 进程A (写入端) int fd = open("/tmp/my_pipe", O_WRONLY); write(fd, "Hello", 6); // 进程B (读取端) int fd = open("/tmp/my_pipe", O_RDONLY); char buf[20]; read(fd, buf, sizeof(buf));
关键注意事项
-
持久性
-
命名管道会持续存在于文件系统中,直到被显式删除
-
即使没有进程使用,管道文件仍然存在
-
需要手动删除:
unlink("/tmp/my_pipe")
-
-
权限控制
-
通过文件权限位(创建时设置的mode参数)控制访问
-
典型权限:
0666
(允许所有用户读写)
-
-
与匿名管道的区别
特性 命名管道(FIFO) 匿名管道 标识 文件系统路径 文件描述符 进程关系 任意进程 必须有关联 生命周期 持久性 随进程结束 创建方式 mkfifo() pipe()
命名管道通过文件系统路径名这一全局命名空间,为无关进程提供了可靠的通信通道,是Unix/Linux系统中重要的IPC机制之一。