关于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();
    });
}
相关推荐
林开落L几秒前
前缀和算法习题篇(上)
c++·算法·leetcode
Prejudices13 分钟前
C++如何调用Python脚本
开发语言·c++·python
单音GG16 分钟前
推荐一个基于协程的C++(lua)游戏服务器
服务器·c++·游戏·lua
qing_04060333 分钟前
C++——多态
开发语言·c++·多态
孙同学_33 分钟前
【C++】—掌握STL vector 类:“Vector简介:动态数组的高效应用”
开发语言·c++
charlie1145141911 小时前
Qt Event事件系统小探2
c++·qt·拖放·事件系统
iiiiiankor1 小时前
C/C++内存管理 | new的机制 | 重载自己的operator new
java·c语言·c++
小狮子安度因1 小时前
Qt滑动条美化自定义
qt
小辛学西嘎嘎1 小时前
C/C++精品项目之图床共享云存储(3):网络缓冲区类和main
c语言·开发语言·c++
c语言鹌鹑蛋2 小时前
C++初阶 --- 类和对象(1)
开发语言·c++