Qt多进程(九)命名管道FIFO

前言

之前在Windows环境下学习多进程ipc通信,总感觉少了点什么。刚好电脑里有Ubuntu虚拟机,里面也有qt环境,所以还是想实际跑一下Linux环境下的几种常见的进程间通信方式,加深理解。

本节中介绍的是命名管道FIFO,顾名思义我们需要创建一个指定名字的管道文件,然后利用它进行读写通信。它的概念和使用方法和之前的都有些相似,所以就不多说了。

一、命名管道(FIFO)

FIFO(First In, First Out) 是一种特殊类型的文件,它允许无关进程通过一个路径名进行通信。数据按顺序写入和读出,先进先出。

它有以下关键特性

1.有文件路径 ,如 /tmp/myfifo,像普通文件一样出现在文件系统中

2.不占磁盘空间,数据存在内核缓冲区中,不会写入硬盘

3.打开时阻塞 ,如果只有读端打开,会等写端;反之亦然(除非用 O_NONBLOCK)

4.单向通信 ,一个 FIFO 只能单向:要么读,要么写(要双向需两个 FIFO)

5.支持多对一/一对多 多个写者 → 一个读者(消息会交错!需协议分隔)

多个读者 ← 一个写者(只有一个读者能收到!)

⚠️ 重要:多个读者时,内核会随机选一个进程投递消息,其他读者收不到!所以通常是一对一或一写多读(但多读需自己协调)。

FIFO适合什么场景,有什么应用呢?

1.简单进程通信 两个无关程序(比如 Python 脚本和 C 程序)通过 /tmp/xxx 交换数据

2.调试友好 你可以用 cat、echo、hexdump 直接查看/注入数据

3.无需网络 比 TCP 快,比共享内存简单

4.天然同步 写者会等读者准备好(避免消息丢失)

实际应用例子

1.日志收集器

多个服务把日志写入 /var/log/app.fifo

一个日志守护进程从 FIFO 读取并写入文件或上传

2.控制接口

一个后台服务监听 /tmp/control.fifo

用户执行 echo "reload" > /tmp/control.fifo 来触发重载配置

3.Shell 脚本协作

二、终端测试

和之前的代码测试不同,fifo文件可以在终端直接通过Linux命令创建,并在两个终端中实现通信。

终端1:

(1)mkfifo /tmp/myfifo,在临时路径下创建管道文件

(2)ls -l /tmp/myfifo,确保文件生成成功

(3)cat/tmp/myfifo,将文件内容输出到终端。此时阻塞等待有内容可以输出。

终端2:

(4)echo "hello from writer!" > /tmp/myfifo,将文本内容输入到管道文件中

终端1:

(1)显示出终端2输入的内容,并退出

事后检查管道文件仍然存在,且可以重复利用。但一段时间后可能会被删除。

三、代码测试

新建writer.c:(稍微解释一下0666的意思,实际上等价于chmod 666 /tmp/myfifo,赋予了这个文件的rw读写权限。13则是字符串长度。)

cpp 复制代码
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>

int main() {
    mkfifo("/tmp/myfifo", 0666);
    int fd = open("/tmp/myfifo", O_WRONLY);
    write(fd, "Hello FIFO!\n", 13);
    close(fd);
    return 0;
}

新建reader.c:

cpp 复制代码
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

int main() {
    int fd = open("/tmp/myfifo", O_RDONLY);
    char buf[100];
    read(fd, buf, sizeof(buf));
    printf("Read: %s", buf);
    close(fd);
    unlink("/tmp/myfifo"); // 删除
    return 0;
}

四、总结

看上去,这也是属于利用文件进行通信的一种方式。但实际上还是有点区别的,fifo文件的存储位置在内核内存缓冲区,它的性能相比于真实的磁盘文件来说,效率会高一些。而且过程中自带原子性,内核也会自动阻塞和环形。如果需要高性能的本地ipc,fifo会比普通的文件队列更好。但如果考虑到崩溃后消息不丢,普通文件队列因为可以存储,会更加可靠。

相关推荐
上天_去_做颗惺星 EVE_BLUE4 分钟前
Docker高效使用指南:从基础到实战模板
开发语言·ubuntu·docker·容器·mac·虚拟环境
2401_857683545 分钟前
C++中的原型模式
开发语言·c++·算法
s1hiyu14 分钟前
C++动态链接库开发
开发语言·c++·算法
(❁´◡`❁)Jimmy(❁´◡`❁)15 分钟前
CF2188 C. Restricted Sorting
c语言·开发语言·算法
星火开发设计20 分钟前
C++ 预处理指令:#include、#define 与条件编译
java·开发语言·c++·学习·算法·知识
许泽宇的技术分享22 分钟前
第 1 章:认识 Claude Code
开发语言·人工智能·python
45288655上山打老虎22 分钟前
QFileDialog
c++
AIFQuant36 分钟前
如何利用免费股票 API 构建量化交易策略:实战分享
开发语言·python·websocket·金融·restful
Hx_Ma1637 分钟前
SpringMVC返回值
java·开发语言·servlet
独自破碎E43 分钟前
【滑动窗口+字符计数数组】LCR_014_字符串的排列
android·java·开发语言