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

发布时间:2026/6/10 20:04:21

进程间通信方式(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它会阻塞等待再启动 writerreader 会立即打印收到的消息。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_castint*(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 进程间通信学习有帮助。

相关新闻