Qt 进程间通信(IPC)全方案

Qt 进程间通信(IPC)全方案

Qt 提供多套跨平台 IPC 方案 ,按使用难度、性能、场景分类整理,附用法、优缺点、示例,适配 Windows/Linux/macOS。

一、方案总览(选型速查表)

表格

方案 跨平台 适用场景 性能 复杂度
QLocalSocket / QLocalServer 全平台 本机进程通信、大数据、实时交互
QSharedMemory 共享内存 全平台 超大内存数据、只读 / 低频交互 极高
QProcess + 标准 IO 全平台 主进程调用子进程、简单文本交互 极低
Qt D-Bus Linux/macOS (部分) Linux 桌面进程调用、系统服务 中高
TCP Socket (QTcpSocket/QTcpServer) 全平台 跨机器 + 本机通用、网络 / 进程二合一
信号量 / 管道 / 文件 全平台 简单标记、少量数据、临时交互

日常开发首选: 本机高频通信 → QLocalSocket 超大块数据共享 → QSharedMemory 拉起子进程 + 简单传参 → QProcess Linux 桌面程序 / 系统交互 → D-Bus


二、逐个方案实战(附可运行代码)

1. QLocalSocket / QLocalServer(最推荐,本机进程通信首选

基于本地命名管道 ,纯 Qt 封装,用法和 TCP Socket 几乎一致,无端口冲突、安全性高、速度快

服务端(被连接进程)

cpp

运行

复制代码
#include <QLocalServer>
#include <QLocalSocket>
#include <QDebug>

class IpcServer : public QObject
{
    Q_OBJECT
public:
    QLocalServer *m_server;
    QLocalSocket *m_clientSocket = nullptr;

    IpcServer()
    {
        m_server = new QLocalServer(this);
        // 清理残留同名服务(防止上次崩溃残留)
        QLocalServer::removeServer("MyIpcServer");

        if (!m_server->listen("MyIpcServer"))
        {
            qDebug() << "服务启动失败:" << m_server->errorString();
            return;
        }
        qDebug() << "本地服务已启动";

        connect(m_server, &QLocalServer::newConnection, this, &IpcServer::onNewConnect);
    }

private slots:
    void onNewConnect()
    {
        m_clientSocket = m_server->nextConnection();
        qDebug() << "客户端已连接";

        connect(m_clientSocket, &QLocalSocket::readyRead, this, &IpcServer::onReadData);
        connect(m_clientSocket, &QLocalSocket::disconnected, m_clientSocket, &QLocalSocket::deleteLater);

        // 回复客户端
        m_clientSocket->write("Hello Client from Server!");
    }

    void onReadData()
    {
        QByteArray data = m_clientSocket->readAll();
        qDebug() << "收到数据:" << data;
    }
};

客户端(主动连接进程)

cpp

运行

复制代码
#include <QLocalSocket>
#include <QDebug>

class IpcClient : public QObject
{
    Q_OBJECT
public:
    QLocalSocket *m_socket;

    IpcClient()
    {
        m_socket = new QLocalSocket(this);
        m_socket->connectToServer("MyIpcServer");

        connect(m_socket, &QLocalSocket::connected, [](){
            qDebug() << "连接服务端成功";
        });
        connect(m_socket, &QLocalSocket::readyRead, this, &IpcClient::onRead);
        connect(m_socket, QOverload<QLocalSocket::LocalSocketError>::of(&QLocalSocket::errorOccurred),
                this, &IpcClient::onError);
    }

    // 发送数据
    void sendMsg(const QString &msg)
    {
        if(m_socket->isOpen())
            m_socket->write(msg.toUtf8());
    }

private slots:
    void onRead()
    {
        QByteArray data = m_socket->readAll();
        qDebug() << "客户端收到:" << data;
    }

    void onError(QLocalSocket::LocalSocketError err)
    {
        qDebug() << "连接错误:" << m_socket->errorString();
    }
};

特点

  • 纯内存通信,速度快,支持二进制、大数据流
  • 只限于本机,不会暴露到外网
  • 读写异步,配合 readyRead 使用,写法成熟稳定

2. QSharedMemory 共享内存(超大块数据首选

多进程共享同一块物理内存 ,数据零拷贝,适合:图像、波形、大缓存、高频大数据。 配合 QSystemSemaphore同步互斥,防止读写冲突。

写入进程(创建共享内存)

cpp

运行

复制代码
#include <QSharedMemory>
#include <QSystemSemaphore>
#include <QDebug>

void writeSharedMem()
{
    // 信号量:保证同步
    QSystemSemaphore sem("MySem", 1);
    sem.acquire(); // 加锁

    QSharedMemory shm("MyShareMem");
    // 创建 1024 字节共享内存
    if (!shm.create(1024))
    {
        qDebug() << "创建失败:" << shm.errorString();
        sem.release();
        return;
    }

    // 写入数据
    char *data = (char*)shm.data();
    QString str = "This is Shared Memory Data";
    memcpy(data, str.toUtf8().data(), str.size());

    sem.release(); // 解锁
    qDebug() << "数据写入共享内存完成";
}

读取进程(挂载共享内存)

cpp

运行

复制代码
void readSharedMem()
{
    QSystemSemaphore sem("MySem", 1);
    sem.acquire();

    QSharedMemory shm("MyShareMem");
    if (!shm.attach())
    {
        qDebug() << "挂载失败:" << shm.errorString();
        sem.release();
        return;
    }

    char *data = (char*)shm.data();
    qDebug() << "读取数据:" << QString(data);

    shm.detach(); // 脱离共享内存
    sem.release();
}

关键点

  1. Key 必须一致MyShareMemMySem 两端完全相同
  2. 必须用 QSystemSemaphore 做互斥,否则多进程同时读写会乱码 / 崩溃
  3. 进程退出前 detach(),主进程退出后共享内存自动释放
  4. 优点:速度天花板级别,适合图像、视频、海量点位数据

3. QProcess + 标准输入输出(父子进程简单通信)

适合:主程序启动子进程,传递参数、接收子进程控制台输出。 纯文本交互,最简单,无需额外 IPC 组件。

主进程(启动子进程 + 收发数据)

cpp

运行

复制代码
#include <QProcess>
#include <QDebug>

QProcess *m_process;

void startSubProcess()
{
    m_process = new QProcess(this);
    // 启动另一个 Qt 程序路径
    m_process->start("./sub_app");

    // 接收子进程输出
    connect(m_process, &QProcess::readyReadStandardOutput, [=](){
        QString out = m_process->readAllStandardOutput();
        qDebug() << "子进程输出:" << out;
    });

    // 向子进程写入数据
    m_process->write("Hello SubProcess\n");
}

子进程(读取标准输入)

cpp

运行

复制代码
// 子进程 main 函数中
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QTextStream in(stdin);
    QString msg = in.readLine();
    qDebug() << "子进程收到:" << msg;

    // 输出给父进程
    QTextStream out(stdout);
    out << "I am Sub Process" << endl;

    return a.exec();
}

特点

  • 用法最简单,适合调用外部程序
  • 基于管道,不适合二进制大数据、高频交互
  • 跨平台通用

4. QTcpSocket / QTcpServer(网络 Socket,本机 + 跨机器通用)

本机进程当成 127.0.0.1 网络通信 ,写法和网络编程一致。 适合:未来可能跨机器部署、不想区分本地 / 网络两套代码。

cpp

运行

复制代码
// 服务端
QTcpServer *tcpServer = new QTcpServer(this);
tcpServer->listen(QHostAddress::LocalHost, 8888);

// 客户端
QTcpSocket *tcpClient = new QTcpSocket(this);
tcpClient->connectToHost(QHostAddress::LocalHost, 8888);

缺点:占用端口,可能端口冲突;本机性能略弱于 QLocalSocket


5. D-Bus(Linux 专属)

Linux 桌面环境标准 IPC,常用于:

  • 桌面通知、系统服务调用
  • 多个桌面组件互相调用

仅 Linux 主流使用 ,Windows/macOS 基本不用,Qt 需开启 dbus 模块:

qmake

复制代码
QT += dbus

适合做远程方法调用 (RPC),可以直接调用对方类的槽函数,语法类似信号槽。


三、场景化选型建议(直接照选)

  1. 同机器两个独立程序,频繁收发消息 / 二进制数据QLocalSocket(首选,稳定、简单、高效)

  2. 多进程共享一张大图、波形数据、大缓冲区QSharedMemory + QSystemSemaphore

  3. 主程序启动子进程,简单传参、看日志输出QProcess 标准 IO

  4. 程序未来要支持跨电脑通信,本地 / 网络一套代码QTcpSocket 本地回环 127.0.0.1

  5. Linux 桌面软件、和系统服务 / 桌面组件交互D-Bus

  6. 极简单标记、少量文本 → 临时文件、注册表 (Windows)、环境变量(不推荐做正式 IPC)


四、通用避坑要点

  1. 命名统一 QLocalServer、QSharedMemory、QSystemSemaphore 的名称两端必须完全一致

  2. 残留清理 程序崩溃会残留本地服务 / 共享内存,启动时执行:

    cpp

    运行

    复制代码
    QLocalServer::removeServer("xxx");
  3. 多线程 Socket / 共享内存不要跨线程直接操作,遵循 Qt 线程规则,数据转发到主线程。

  4. 二进制数据 优先 QLocalSocket / 共享内存,不要用 QProcess 标准 IO(易乱码、分包)。

  5. Release 模式 IPC 大量数据传输时,Debug 会明显变慢,正式部署务必 Release。

相关推荐
小短腿的代码世界5 小时前
Qt Bluetooth源码深度解析:从HCI协议到跨平台API的完整架构
开发语言·qt·架构
小短腿的代码世界5 小时前
Qt WebEngine多进程架构与IPC通信:从Chromium多进程到Qt信号槽融合
qt·架构·系统架构
尘中远7 小时前
【Qwt 7.0 系列】快速入门与核心新特性概览 —— 更现代的 Qt 数据可视化库
qt·数据可视化·绘图·qwt·科学绘图
初阳7859 小时前
【Qt】系统相关(3)——多线程
qt
初阳78512 小时前
【Qt】系统相关(2)——文件
开发语言·qt
尘中远1 天前
【Qwt 7.0 系列】坐标轴与刻度系统 —— 刻度引擎、网格、图例与刻度朝内
qt·数据可视化·qcustomplot·qwt·工业软件·科学绘图
sycmancia1 天前
Qt——多线程间的互斥
开发语言·qt
尘中远1 天前
【Qwt 7.0 系列】常用图表类型实战 —— 柱状图、散点图、箱线图与直方图
qt·qwt·工业软件·科学绘图
尘中远1 天前
【Qwt 7.0 系列】交互功能详解 —— 平移、缩放、坐标轴交互与数据拾取
qt·数据可视化·绘图·qcustomplot·qwt·科学绘图
sycmancia1 天前
Qt——进程与线程的概念
qt