关于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();
    });
}
相关推荐
Darkwanderor40 分钟前
三分算法的简单应用
c++·算法·三分法·三分算法
2401_831920741 小时前
分布式系统安全通信
开发语言·c++·算法
2401_877274241 小时前
从匿名管道到 Master-Slave 进程池:Linux 进程间通信深度实践
linux·服务器·c++
汉克老师2 小时前
GESP5级C++考试语法知识(八、链表(三)循环链表)
c++·约瑟夫问题·循环链表·gesp5级·gesp五级
阿贵---2 小时前
C++中的RAII技术深入
开发语言·c++·算法
PiKaMouse.2 小时前
navigation2-humble从零带读笔记第一篇:nav2_core
c++·算法·机器人
vistaup3 小时前
windows git 更新当前目录下所有的文件(非递归)
windows·git
lightqjx3 小时前
【算法】二分算法
c++·算法·leetcode·二分算法·二分模板
娇娇yyyyyy3 小时前
QT编程(17): Qt 实现自定义列表模型
开发语言·qt
Irissgwe4 小时前
进程间通信
linux·服务器·网络·c++·进程间通信