QProcess 的管道通信支持多次双向交互,并非仅限单次消息传递。以下是详细说明:
1. QProcess 管道通信原理
- 标准流重定向:QProcess 默认将子进程的
stdin/stdout/stderr
映射到父进程的管道。 - 双向通信:父进程可随时通过
write()
向子进程发送数据,子进程也可通过stdout
持续输出结果。
2. 实现多次通信的示例
父进程代码
QProcess process;
process.start("child_app"); // 启动子进程
// 发送第一条消息
process.write("Hello from Parent!\n"); // 注意添加换行符(若子进程按行读取)
process.flush(); // 确保数据立即发送
// 读取子进程响应
if (process.waitForReadyRead()) {
QString response = process.readAllStandardOutput();
qDebug() << "子进程回复:" << response;
}
// 发送第二条消息
process.write("Another message!\n");
process.flush();
// 再次读取响应
if (process.waitForReadyRead()) {
QString response2 = process.readAllStandardOutput();
qDebug() << "子进程二次回复:" << response2;
}
process.close(); // 关闭进程
子进程代码(child_app)
#include <QCoreApplication>
#include <QTextStream>
int main(int argc, char *argv[]) {
QCoreApplication a(argc, argv);
QTextStream in(stdin);
QTextStream out(stdout);
while (!in.atEnd()) {
QString line = in.readLine(); // 按行读取父进程输入
out << "收到: " << line << "\n"; // 回复父进程
out.flush(); // 确保立即发送
}
return a.exec();
}
3. 关键点
- 持续读写
- 父进程可多次调用
write()
发送数据,子进程通过循环(如while (!in.atEnd())
)持续接收。 - 子进程的每次输出都会触发父进程的
readyReadStandardOutput
信号(若使用异步模式)。
- 父进程可多次调用
- 缓冲区管理
- 使用
flush()
确保数据立即发送,避免因缓冲区未满导致延迟。 - 父进程需及时读取子进程输出,防止阻塞子进程(尤其在使用
waitForReadyRead
时)。
- 使用
- 协议设计
- 定义明确的消息边界(如换行符
\n
或固定长度),避免数据粘连。 - 可使用
QDataStream
传输结构化数据(如 JSON、二进制协议)。
- 定义明确的消息边界(如换行符
4. 异步模式优化
父进程(异步)
QProcess process;
process.start("child_app");
// 连接子进程输出信号
connect(&process, &QProcess::readyReadStandardOutput, [&]() {
QString response = process.readAllStandardOutput();
qDebug() << "子进程回复:" << response;
});
// 发送消息(非阻塞)
process.write("Async message 1\n");
process.flush();
// 稍后再次发送
QTimer::singleShot(1000, [&]() {
process.write("Async message 2\n");
process.flush();
});
子进程(同上)
5. 注意事项
- 进程生命周期:子进程退出后,管道自动关闭,无法继续通信。
- 错误处理:检查
QProcess::error()
和QProcess::exitStatus()
处理异常。 - 跨平台行为:Windows 下子进程可能继承父进程的控制台,需测试输出行为。
总结
QProcess 管道通信完全支持多次双向交互,关键在于:
- 子进程设计为持续监听输入(如循环读取)。
- 父进程及时读写数据,避免缓冲区阻塞。
- 定义清晰的消息协议确保数据完整性。
此机制适用于命令行工具集成、实时日志处理等场景,性能优于本地套接字(因无系统调用开销)。