关于QProcess子进程导致的当前进程内存持续升高问题

关于QProcess子进程导致的当前进程内存持续升高问题

背景

程序A使用QProcess启动程序B,并遍历当前系统里的窗口句柄,寻找到B的窗口并嵌入A的窗口中

c++ 复制代码
void TestUnit::init() {
    connect(mpProcess, &QProcess::started, this, [this]() {
        mpWidget = findProcessWidget(mpProcess);
        mbStatus = true;
        emit tessInited();
	});

    auto tessPath = QCoreApplication::applicationDirPath() + "/xxx.exe";
    mpProcess->start(tessPath);
}

现象

随着TESS NG仿真任务的不断进行,当前程序的内存持续升高,且步幅越来越大,速度越来越快

原因

enum QProcess::ProcessChannelMode

该枚举描述了进程输出通道模式QProcess。将这些值之一传递给setProcessChannelMode() 设置当前读取通道模式。

持续的 价值 描述
QProcess::SeparateChannels 0 QProcess 管理运行进程的输出,将标准输出和标准错误数据保存在不同的内部缓冲区中。通过调用 setReadChannel() 可以选择 QProcess 当前的读取通道。这是 QProcess 的默认通道模式。
QProcess::MergedChannels 1 QProcess 会将运行进程的输出合并到标准输出通道 (stdout) 中。标准错误通道(stderr)不会接收任何数据。运行进程的标准输出和标准错误数据会交错排列。对于分离进程,运行进程的合并输出将转发给主进程。
QProcess::ForwardedChannels 2 QProcess 会将运行进程的输出转发给主进程。子进程写入其标准输出和标准错误的任何内容都将写入主进程的标准输出和标准错误。
QProcess::ForwardedErrorChannel 4 QProcess 管理运行进程的标准输出,但会将标准错误转发给主进程。这反映了命令行工具作为过滤器的典型用途,即标准输出被重定向到另一个进程或文件,而标准错误被打印到控制台,用于诊断目的。(此值在 Qt 5.2 中引入)
QProcess::ForwardedOutputChannel 3 是 ForwardedErrorChannel 的补充。(该值在 Qt 5.2 中引入)。

注意: Windows 会有意抑制从纯图形用户界面应用程序到继承控制台的输出。这不适用于重定向到文件或管道的输出。要在控制台上转发纯图形用户界面应用程序的输出,必须使用 SeparateChannels,并通过读取输出并将其写入适当的输出通道来自行完成转发。

​ 当调用QProcess的start()函数启动子进程时,QProcess会为子进程创建三个管道:标准输入、标准输出和标准错误。这些管道将被用于子进程与主进程之间的通信。在使用管道通信时,需要确保适当地处理子进程的输出和错误信息。否则,如果子进程输出过多的数据或发生错误,可能会导致管道阻塞,从而导致主进程挂起或崩溃。

解决办法

c++ 复制代码
void TestUnit::init() {
    connect(mpProcess, &QProcess::started, this, [this]() {
        mpWidget = findProcessWidget(mpProcess);
        mbStatus = true;
        emit tessInited();
    });

    auto tessPath = QCoreApplication::applicationDirPath() + "/xxx.exe";
    mpProcess->start(tessPath, QProcess::Truncate);

    QObject::connect(mpProcess, &QProcess::readyReadStandardOutput, [&]() {
        auto output = mpProcess->readAllStandardOutput();
    });
    QObject::connect(mpProcess, &QProcess::readyReadStandardError, [&]() {
        auto errorOutput = mpProcess->readAllStandardError();
    });
}
相关推荐
汉字萌萌哒21 分钟前
2019CCF-CSP入门级C++试题解析
java·开发语言·c++
2401_890603401 小时前
C++ 继承
c++
果果燕2 小时前
C++ 学习笔记(二):类与对象—— 构造函数与析构函数
开发语言·c++
老洋葱Mr_Onion2 小时前
【C++】信息学奥赛CSP通关之路——CSP-J/S第一轮原创全真模拟试卷集(2026)卷四全卷解析
开发语言·c++
布莱克6052 小时前
理解 C/C++ 中的 void* 指针
c语言·c++
小小龙学IT4 小时前
simdjson:利用 SIMD 指令实现 GB/s 级 JSON 解析的 C++ 开源库
开发语言·c++·json
不正经学生5 小时前
C语言字符串函数进阶:安全版函数 + 错误处理 + 子串查找
c语言·开发语言·c++·算法·面试
三克的油5 小时前
算法基础-1
数据结构·c++·算法
戒了,最后一次5 小时前
Windows 安装 FFmpeg 完整教程(附环境变量配置 + 常用命令示例)
windows·ffmpeg
鸿芯微控科技5 小时前
MFC量程怎么选?最小流量、满量程、调节比与误差计算
c++·python·mfc·流量控制·设备选型·质量流量控制器