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会比普通的文件队列更好。但如果考虑到崩溃后消息不丢,普通文件队列因为可以存储,会更加可靠。

相关推荐
聆风吟º9 小时前
【C++藏宝阁】C++入门:命名空间(namespace)详解
开发语言·c++·namespace·命名空间
ybb_ymm9 小时前
尝试新版idea及免费学习使用
java·学习·intellij-idea
优雅的潮叭9 小时前
c++ 学习笔记之 模板元编程
c++·笔记·学习
潇潇云起9 小时前
mapdb
java·开发语言·数据结构·db
飞鹰519 小时前
CUDA入门:从Hello World到矩阵运算 - Week 1学习总结
c++·人工智能·性能优化·ai编程·gpu算力
prettyxian9 小时前
【QT】信号与槽基础:手动连接的原理与实践
开发语言·qt
君鼎9 小时前
计算机网络第五章:传输层学习总结
学习·计算机网络
xian_wwq9 小时前
【学习笔记】网络安全L3级模型功能解析
笔记·学习·安全
傻乐u兔9 小时前
C语言初阶————结构体
c语言·开发语言