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。

相关推荐
雪的季节3 小时前
Qt Graphs 2D+3D介绍
qt·3d
小鹏linux3 小时前
鸿蒙PC迁移:TupiTube Desk Qt 2D 动画工作室鸿蒙PC适配全记录
qt·华为·harmonyos
鸽芷咕4 小时前
鸿蒙PC迁移:LANDrop Qt 局域网传输工具鸿蒙PC适配全记录
qt·华为·harmonyos
Lhan.zzZ4 小时前
Qt Quick 嵌套 Dialog 与 ComboBox 层级混乱问题解决
c++·qt
森G4 小时前
67、Qt 多媒体框架概述---------多媒体
开发语言·qt
鸽芷咕4 小时前
鸿蒙PC迁移:MoonPlayer Qt 视频播放器鸿蒙PC适配全记录
qt·音视频·harmonyos
小鹏linux5 小时前
鸿蒙PC迁移:Phototonic Qt 图片查看器鸿蒙适配全记录:一次从 Widgets 桌面应用到 HAP 的迁移
qt·华为·harmonyos
knighthood20015 小时前
鸿蒙PC迁移:KeePassXC Qt 密码管理器鸿蒙PC适配全记录
qt·华为·harmonyos
luoyayun3615 小时前
Qt 中使用 QtConcurrent::run + QFutureWatcher 实现异步处理
qt·异步·qtconcurrent