关于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();
    });
}
相关推荐
阿昭L1 小时前
Windows键盘过滤
windows·驱动开发·windows内核·过滤驱动
苦青藤7 小时前
从零搭建 WSUS 隔离网络:完整实战指南(内网离线补丁分发)
运维·windows·microsoft
feng_you_ying_li13 小时前
C++复习二,继承与多态
c++
小小de风呀13 小时前
de风——【从零开始学C++】(十一):list的基本使用和模拟实现
开发语言·c++·list
陌路2013 小时前
C++高级进阶--夯实进阶基础(1)
开发语言·c++
Smoothcloud润云15 小时前
5大功能精修,重构AI算力使用体验!
java·人工智能·windows·算法·重构·编辑器·sublime text
郝学胜-神的一滴15 小时前
中级OpenGL教程 008:精准控制高光光斑大小与强度
c++·unity·godot·three.js·图形学·opengl·unreal
牢姐与蒯15 小时前
c++数据结构之c++11(一)
数据结构·c++
ModestCoder_15 小时前
windows/ubuntu解决挂梯子但是codex reconnecting五次的问题
linux·windows·ubuntu
折戟不必沉沙15 小时前
构造和析构函数能否是虚函数?能否调用虚函数?
c++