news 2026/6/10 20:04:20

进程间通信方式(QT实现案例)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
进程间通信方式(QT实现案例)

用 Qt 实现几种最常用的进程间通信方式。


1. 匿名管道 —— 用 QProcess 父子通信

原理:父进程启动子进程,通过标准输入/输出管道传递数据。Qt 的QProcess封装了这一切。

父进程(发送数据)

// parent/main.cpp #include <QCoreApplication> #include <QProcess> #include <QDebug> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QProcess child; child.start("./child"); // 启动编译好的子进程 child.waitForStarted(); child.write("Hello from parent\n"); // 写入子进程的标准输入 child.closeWriteChannel(); // 关闭输入,让子进程知道结束 child.waitForFinished(); qDebug() << "Child output:" << child.readAllStandardOutput(); return 0; }

子进程(接收数据)

// child/main.cpp #include <QCoreApplication> #include <QTextStream> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QTextStream in(stdin); QString line = in.readLine(); QTextStream out(stdout); out << "I received: " << line << Qt::endl; return 0; }

编译运行:两个工程都编译后,在同一目录下运行 parent,会看到子进程把收到的消息打印回来。


2. 命名管道(FIFO) —— 用 QFile 读写

原理:Linux 下创建特殊文件(管道文件),无亲缘关系的进程可以像操作普通文件一样用QFile打开它,但数据不会落盘。

公共准备:创建管道文件(只需一次)

在终端执行:

mkfifo /tmp/myfifo

写入进程

// writer/main.cpp #include <QCoreApplication> #include <QFile> #include <QDebug> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QFile fifo("/tmp/myfifo"); if (!fifo.open(QIODevice::WriteOnly)) { qDebug() << "Cannot open FIFO for writing"; return 1; } fifo.write("Hello via FIFO\n"); fifo.close(); return 0; }

读取进程

// reader/main.cpp #include <QCoreApplication> #include <QFile> #include <QDebug> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QFile fifo("/tmp/myfifo"); if (!fifo.open(QIODevice::ReadOnly)) { qDebug() << "Cannot open FIFO for reading"; return 1; } qDebug() << "Received:" << fifo.readAll(); fifo.close(); return 0; }

运行:先启动 reader(它会阻塞等待),再启动 writer,reader 会立即打印收到的消息。


3. 本地套接字 —— QLocalServer / QLocalSocket

原理:同机进程间类似网络通信,但不需要 IP,使用文件名作为地址。

服务端

// server/main.cpp #include <QCoreApplication> #include <QLocalServer> #include <QLocalSocket> #include <QDebug> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); const QString name = "qt_local_socket"; QLocalServer::removeServer(name); QLocalServer server; server.listen(name); QObject::connect(&server, &QLocalServer::newConnection, [&]() { QLocalSocket *client = server.nextPendingConnection(); QObject::connect(client, &QLocalSocket::readyRead, [client]() { QByteArray data = client->readAll(); qDebug() << "Server got:" << data; client->write("Echo: " + data); client->disconnectFromServer(); }); }); qDebug() << "Server listening..."; return a.exec(); }

客户端

// client/main.cpp #include <QCoreApplication> #include <QLocalSocket> #include <QDebug> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QLocalSocket socket; socket.connectToServer("qt_local_socket"); if (!socket.waitForConnected(3000)) { qDebug() << "Connection failed"; return 1; } socket.write("Hello socket!"); socket.waitForBytesWritten(); if (socket.waitForReadyRead(3000)) { qDebug() << "Reply:" << socket.readAll(); } return 0; }

注意.pro文件中要加QT += network


4. 共享内存 + 信号量 —— QSharedMemory + QSystemSemaphore

原理:Qt 封装了跨平台的共享内存和进程间信号量,适合快速交换数据并保证互斥。

任意进程(写入/读取同一个计数器)

// shared_counter/main.cpp #include <QCoreApplication> #include <QSharedMemory> #include <QSystemSemaphore> #include <QDebug> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QSystemSemaphore sem("counter_sem", 1, QSystemSemaphore::OpenOrCreate); QSharedMemory shm("counter_shm"); if (!shm.create(sizeof(int))) { // 已经存在,附加 if (!shm.attach()) { qDebug() << "Attach failed"; return 1; } } sem.acquire(); // 加锁 int *counter = static_cast<int*>(shm.data()); *counter += 1; qDebug() << "Current counter:" << *counter; sem.release(); // 解锁 // 清理(最后一个退出的进程执行) // shm.detach(); // 这里为了演示不销毁 return 0; }

运行:编译后多次启动这个程序,每次都会看到计数器递增,并且不会混乱。


5. 信号(Signal) —— QProcess 发送/接收

原理:Unix 信号是一种异步通知机制。Qt 中可用QProcess向进程发送信号,但接收信号需要配合低层 API,这里只演示发送。

发送方

// signal_sender/main.cpp #include <QCoreApplication> #include <QProcess> #include <QDebug> #include <signal.h> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QProcess process; process.start("./receiver"); // 启动一个长期运行的程序 process.waitForStarted(); qDebug() << "Sending SIGUSR1 to" << process.processId(); // 方式1:使用 kill 系统调用 kill(process.processId(), SIGUSR1); // 方式2:使用 QProcess::terminate() 发送 SIGTERM // process.terminate(); process.waitForFinished(3000); return 0; }

接收方(需处理信号)

// receiver/main.cpp #include <QCoreApplication> #include <QDebug> #include <signal.h> #include <unistd.h> // 信号处理函数(尽量简单) void handleSigUsr1(int) { qDebug() << "SIGUSR1 received!"; } int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); signal(SIGUSR1, handleSigUsr1); qDebug() << "Receiver PID:" << getpid() << " waiting..."; // 让程序保持运行,等待信号 QTimer::singleShot(5000, &a, &QCoreApplication::quit); return a.exec(); }

注意:接收方需要<signal.h>和 Unix 环境。


小结

IPC 方式Qt 实现类适用场景
匿名管道QProcess(标准输入/输出)父子进程单向数据流
命名管道QFile(操作 FIFO 文件)无关进程间的流式通信
本地套接字QLocalServer / QLocalSocket多对多、结构化的命令交换
共享内存+信号量QSharedMemory + QSystemSemaphore大数据量、高频访问
信号kill() / QProcess::terminate()简单事件通知、进程控制

希望对你的 Qt 进程间通信学习有帮助。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/10 20:00:41

2026年|如何快速去除论文AI痕迹?10款智能工具高效降低AI率

现在谁还没靠AI救过急啊&#xff01;学生赶毕业论文、博主攒日常文案、编辑改期刊稿件&#xff0c;最怕的就是AI痕迹太明显——要么查重过不了&#xff0c;要么被导师一眼看穿&#xff01;我翻遍各种工具亲测对比&#xff0c;整理出一批既能消AIGC痕迹又能顺带降重的神器&#…

作者头像 李华
网站建设 2026/6/10 19:57:25

工商业储能系列:主动均衡之基于单向反激式DCDC分布式均衡方案<LT8584>

⚡目标解决问题 对新能源汽车和储能BMS而言&#xff0c;电芯电压一致性是普遍存在的工程难题。主动均衡技术可以解决这一问题&#xff0c;但工程师在选型时经常面临一个根本性的困惑&#xff1a; “集中式主动均衡”和“分布式主动均衡”到底该怎么选&#xff1f;为什么很多资…

作者头像 李华
网站建设 2026/6/10 19:55:23

[量化]《深入理解 shared_ptr 的线程安全:原理、误区与最佳实践》

引言 std::shared_ptr` 是 C++ 中最常用的智能指针之一,但其线程安全语义常常被误解。本文从引用计数的原子操作出发,详细分析 `shared_ptr` 哪些操作是线程安全的、哪些不是,并给出正确的多线程使用模式,帮助你避免数据竞争和未定义行为。适用于 C++11 及以上标准。 1.s…

作者头像 李华
网站建设 2026/6/10 19:55:21

[量化]《Linux 用户态与内核态深度解析:从特权级到切换开销》

# 理解 Linux 用户态与内核态:区别、切换机制与性能优化 > 你是否想过:为什么程序频繁调用 `read`/`write` 会变慢?系统调用到底有多大的开销?本文从 CPU 特权级出发,深入讲解 Linux 用户态与内核态的区别、切换流程、成本分析以及如何减少不必要的切换。读完本文,你…

作者头像 李华
网站建设 2026/6/10 19:53:13

实战房价竞赛

下载数据集 # 导入所需的库 import hashlib # 用于计算文件的SHA-1哈希值&#xff0c;验证文件完整性 import os # 用于操作系统路径、目录等操作 import tarfile # 用于处理.tar或.gz压缩文件 import zipfile # 用于处理.zip压缩文件 import reques…

作者头像 李华
网站建设 2026/6/10 19:53:06

bgp策略

需求&#xff1a;1、使用PreVal策略&#xff0c;确保R4通过R2到达192.168.10.0/24 2、使用AS_Path策略&#xff0c;确保R4通过R3到达192.168.11.0/24 3、配置MED策略&#xff0c;确保R4通过R3到达192.168.12.0/24 4、使用Local Preference策略&#xff0c;确保R1通过R2到达192.…

作者头像 李华