QModbusTCPClient占用内存持续增长

发布于:2025-02-10 ⋅ 阅读:(36) ⋅ 点赞:(0)

    最近使用QModbusTCPClient通信,需要频繁发送读写请求,发现软件占用内存一直在增减,经过不断咨询和尝试,终于解决了。

1.方案一(失败)

最开始以为是访问太频繁,导致创建reply的对象比delete reply快导致的。尝试增加时间间隔,发现无效。内存占用还是在增加,只是增速慢了点。

QModbusReply*reply= m_modbus->sendReadRequest();

2.方案二(失败)

直接保存每个reply,只有reply==nullptr时才能重复发送对应的request()请求。在reply的finish槽函数中delete reply,同时让reply=nullptr。这样可以避免过于频繁的通信,确保前一次request()处理响应之后再次发送相同的request().

if(!m_reply[4])         //确保前一次响应处理之后再次发送相同的request()
    {
        QVector<quint16>values(1, 0);
        QModbusDataUnit read(QModbusDataUnit::Coils, 128 + m_param->motorID(), values);
        m_reply[4] = m_modbus->sendReadRequest(read, m_485ID);

        if(m_reply[4] && !m_reply[4]->isFinished())
        {
            connect(m_reply[4], &QModbusReply::finished, [this]() {
                if(m_reply[4]->error() == QModbusDevice::NoError)
                {
                    m_runState = m_reply[4]->result().values().first();
                }

                delete  m_reply[4];
                m_reply[4] = nullptr;//确保下次可以再次发送request()

            });
        }
        else {
            delete  m_reply[4];
            m_reply[4] = nullptr;
        }
    }

仍然没有解决问题,内存还是在持续增加。

3.方案三(成功)

感谢这里的内容

https://bugreports.qt.io/browse/QTBUG-92072

问题:

//qmodbusclient_p.h ->enqueueRequest
q->connect(q, &QModbusClient::timeoutChanged,
                    element.timer.data(), QOverload<int>::of(&QTimer::setInterval));

QModbusTCPClient的每次request(无论读写)都会增加这样一个连接。即使销毁了对应的reply,也不能删除该链接,导致内存逐渐增加。

解决:

针对每一次request,手动断开该链接。

m_modbus->disconnect(SIGNAL(timeoutChanged(int)), 0, 0);

一段完整代码:

QModbusReply *reply = m_modbus->sendWriteRequest(
                              m_param->modbusData(topLeft),
                              m_485ID);

    int id = m_param->index(topLeft.row(), m_param->IDCol).data().toInt();
    int value = topLeft.data().toInt();
    QString text = m_param->index(topLeft.row(), m_param->TextCol).data().toString();


    if(reply && !reply->isFinished())
    {
        connect(reply, &QModbusReply::finished, [ = ]() {

            if(reply->error() == QModbusDevice::NoError)
            {
                qInfo() << QString("MotorID:%1 Write(%2->%3(%4)) Succeed!\n")
                        .arg(m_param->motorID())
                        .arg(value)
                        .arg(id)
                        .arg(text);
            }
            else
            {
                qWarning() << QString("MotorID:%1 Write(%2->%3(%4)) Failed!\n")
                           .arg(m_param->motorID())
                           .arg(value)
                           .arg(id)
                           .arg(text);
            }

//响应函数中手动断开连接

            m_modbus->disconnect(SIGNAL(timeoutChanged(int)), 0, 0);
            delete  reply;
        });
    }
    else
    {
        qWarning() << QString("MotorID:%1 Write(%2->%3(%4)) No Response!\n")
                   .arg(m_param->motorID())
                   .arg(value)
                   .arg(id)
                   .arg(text);
//响应函数中手动断开连接
        m_modbus->disconnect(SIGNAL(timeoutChanged(int)), 0, 0);
        delete reply;
    }


网站公告

今日签到

点亮在社区的每一天
去签到