欢迎光临中国护送网
详情描述
Linux进程间通信之命名管道(FIFO):跨进程通信的实用方案
Linux进程间通信:命名管道(FIFO)详解 一、什么是命名管道(FIFO)

命名管道是一种特殊的文件类型,允许无亲缘关系的进程之间进行通信。与匿名管道(pipe)不同,FIFO在文件系统中有一个真实的文件名,任何知道该文件名的进程都可以访问它。

二、FIFO的核心特性 持久性:在文件系统中可见,直到被显式删除 半双工:数据单向流动(需要两个FIFO实现双向通信) 阻塞I/O:默认读写操作会阻塞,直到另一端有操作 字节流:数据以字节流形式传输,无消息边界 三、创建与使用FIFO 创建FIFO的两种方式

1. 命令行创建

# 创建命名管道 mkfifo /tmp/myfifo # 查看文件类型 ls -l /tmp/myfifo # 输出:prw-r--r-- 1 user user 0 Jan 1 12:00 /tmp/myfifo # 'p' 表示管道文件

2. 程序内创建

#include <sys/types.h> #include <sys/stat.h> // 创建FIFO,mode为权限(如0666) int mkfifo(const char *pathname, mode_t mode); 四、完整示例:生产者-消费者模型 生产者程序(writer.c) #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> #define FIFO_FILE "/tmp/myfifo" #define BUFFER_SIZE 1024 int main() { int fd; char buff[BUFFER_SIZE]; // 创建FIFO(如果不存在) if (mkfifo(FIFO_FILE, 0666) == -1) { // 可能已存在,继续尝试打开 } printf("生产者启动,等待消费者连接...\n"); // 打开FIFO进行写入(会阻塞直到消费者打开读取端) fd = open(FIFO_FILE, O_WRONLY); while (1) { printf("输入消息 (输入'quit'退出): "); fgets(buff, BUFFER_SIZE, stdin); // 写入FIFO write(fd, buff, strlen(buff)+1); if (strncmp(buff, "quit", 4) == 0) { break; } } close(fd); // unlink(FIFO_FILE); // 可选:删除FIFO文件 return 0; } 消费者程序(reader.c) #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> #define FIFO_FILE "/tmp/myfifo" #define BUFFER_SIZE 1024 int main() { int fd; char buff[BUFFER_SIZE]; printf("消费者启动,等待数据...\n"); // 打开FIFO进行读取(会阻塞直到生产者打开写入端) fd = open(FIFO_FILE, O_RDONLY); while (1) { // 从FIFO读取数据 int bytes_read = read(fd, buff, BUFFER_SIZE); if (bytes_read > 0) { printf("收到消息: %s", buff); if (strncmp(buff, "quit", 4) == 0) { break; } } } close(fd); return 0; } 五、编译与测试 # 编译 gcc writer.c -o writer gcc reader.c -o reader # 终端1:运行消费者 ./reader # 终端2:运行生产者 ./writer 六、高级用法与技巧 1. 非阻塞模式 // 非阻塞方式打开FIFO int fd = open(FIFO_FILE, O_RDONLY | O_NONBLOCK); // 或通过fcntl设置 int flags = fcntl(fd, F_GETFL); fcntl(fd, F_SETFL, flags | O_NONBLOCK); 2. 多客户端服务器模型 // 服务器处理多个客户端 #include <errno.h> void server_handle_multiple_clients() { int fd, bytes; char buffer[256]; mkfifo("/tmp/server_fifo", 0666); while (1) { // 打开服务器FIFO(阻塞等待客户端) fd = open("/tmp/server_fifo", O_RDONLY); // 读取客户端请求 while ((bytes = read(fd, buffer, sizeof(buffer))) > 0) { printf("收到请求: %s\n", buffer); // 创建唯一的响应FIFO名 char response_fifo[50]; sprintf(response_fifo, "/tmp/client_%s_fifo", buffer); // 打开客户端FIFO并发送响应 int resp_fd = open(response_fifo, O_WRONLY); write(resp_fd, "响应数据", 10); close(resp_fd); } close(fd); } } 3. 双向通信实现 // 进程A创建两个FIFO mkfifo("/tmp/AtoB", 0666); mkfifo("/tmp/BtoA", 0666); // 进程A:向AtoB写,从BtoA读 // 进程B:向BtoA写,从AtoB读 七、FIFO的限制与注意事项

容量限制:Linux默认64KB(可配置)

原子性:写入数据量≤PIPE_BUF(通常4096字节)时保证原子性

阻塞问题

  • 读空FIFO会阻塞,直到有数据写入
  • 写满FIFO会阻塞,直到有数据被读取
  • 所有写入端关闭后,读取返回0
  • 所有读取端关闭后,写入会触发SIGPIPE信号

清理问题:FIFO文件需要手动删除

// 删除FIFO文件 unlink("/tmp/myfifo"); 八、与其他IPC方式的对比 特性 命名管道 匿名管道 消息队列 共享内存 无亲缘关系 ✅ ❌ ✅ ✅ 文件系统可见 ✅ ❌ ❌ ❌ 通信方向 半双工 半双工 全双工 全双工 性能 中 高 中 高 数据格式 字节流 字节流 消息 字节流 九、实际应用场景 Shell命令协同 # 终端1:创建并写入FIFO mkfifo /tmp/myfifo echo "Hello World" > /tmp/myfifo 终端2:从FIFO读取

cat < /tmp/myfifo

2. **日志收集系统** ```c // 多个进程向同一个FIFO写入日志 // 日志收集进程从FIFO读取并统一处理 进程池任务分发// 主进程向FIFO写入任务 // 工作进程从FIFO读取并执行 十、最佳实践 错误处理:始终检查系统调用返回值 信号处理:处理SIGPIPE等可能信号 资源清理:程序退出前删除FIFO文件 权限控制:设置适当的文件权限(如0600) 超时机制:使用select/poll防止永久阻塞 // 使用poll实现超时读取 struct pollfd fds[1]; fds[0].fd = fd; fds[0].events = POLLIN; int ret = poll(fds, 1, 3000); // 3秒超时 if (ret > 0 && (fds[0].revents & POLLIN)) { read(fd, buffer, size); }

命名管道作为一种简单有效的进程间通信机制,特别适用于单向数据流无亲缘关系进程的通信场景。虽然功能相对简单,但在许多系统编程场景中仍然非常实用。

相关帖子
海外留学归国人员在国内哪些城市可以享受到专门的人才引进落户补贴?
海外留学归国人员在国内哪些城市可以享受到专门的人才引进落户补贴?
舟山市精准获客软件@品牌网站建设设计,定制开发
舟山市精准获客软件@品牌网站建设设计,定制开发
舟山市病人跨省市转运120救护车-专业接送病人服务车
舟山市病人跨省市转运120救护车-专业接送病人服务车
舟山市网站建设推广-网站改版,服务可靠
舟山市网站建设推广-网站改版,服务可靠
舟山市120救护车出租,车上设备齐全
舟山市120救护车出租,车上设备齐全
青岛市长途120救护车出租转运病人-长途急救车出租,按公里收费
青岛市长途120救护车出租转运病人-长途急救车出租,按公里收费
广元市病人转运救护车出租公司-急救车出租,车内设备齐全
广元市病人转运救护车出租公司-急救车出租,车内设备齐全
遵义市精准获客软件#网站优化推广服务公司,优秀设计团队
遵义市精准获客软件#网站优化推广服务公司,优秀设计团队
针对儿童、老人等特殊群体,2026年会有更专业的预制菜品类吗?
针对儿童、老人等特殊群体,2026年会有更专业的预制菜品类吗?
除了送餐,2026年的外卖骑手还可能承接哪些类型的即时配送服务任务?
除了送餐,2026年的外卖骑手还可能承接哪些类型的即时配送服务任务?
凉山私人救护车长途转院-长途急救车出租,24小时随叫随到
凉山私人救护车长途转院-长途急救车出租,24小时随叫随到
在2026年的劳动监察条例中,对拖欠工资行为的处罚有哪些新规?
在2026年的劳动监察条例中,对拖欠工资行为的处罚有哪些新规?
在2026年,灵活就业人员或自由职业者是否有资格申请当地的住房租赁补贴,如何认定?
在2026年,灵活就业人员或自由职业者是否有资格申请当地的住房租赁补贴,如何认定?
枣庄市购物网站开发@多语言网站建设,企业解决方案
枣庄市购物网站开发@多语言网站建设,企业解决方案
鹰潭市跨省救护车出租转运-救护车转运收费标准
鹰潭市跨省救护车出租转运-救护车转运收费标准
作为自由职业者,2026年个人缴纳社保每月到底需要交多少钱?
作为自由职业者,2026年个人缴纳社保每月到底需要交多少钱?
泰州市网站SEO优化#企业网站开发设计,多年专业建站经验
泰州市网站SEO优化#企业网站开发设计,多年专业建站经验
未来的社保服务体系将如何发展,以更便捷地保障参保人待遇享受?
未来的社保服务体系将如何发展,以更便捷地保障参保人待遇享受?
2026年的零工经济中,从业者的“数据权益”与“算法透明”可能如何得到保障?
2026年的零工经济中,从业者的“数据权益”与“算法透明”可能如何得到保障?