【发布时间】:2016-07-05 10:11:41
【问题描述】:
我使用以下代码与 USB 串行端口设备通信:
#include "masterthread.h"
#include <QtSerialPort/QSerialPort>
#include <QTime>
#include "Windows.h"
#include "Psapi.h"
#include <QDebug>
QT_USE_NAMESPACE
MasterThread::MasterThread(QObject *parent)
: QThread(parent), waitTimeout(0), quit(false)
{
}
MasterThread::~MasterThread()
{
mutex.lock();
quit = true;
cond.wakeOne();
mutex.unlock();
wait();
}
void MasterThread::run()
{
bool currentPortNameChanged = false;
QSerialPort serial;
serial.setPortName("COM3");
serial.setBaudRate(57600);
serial.setStopBits(static_cast<QSerialPort::StopBits>(1));
serial.setDataBits(static_cast<QSerialPort::DataBits>(8));
serial.setParity(static_cast<QSerialPort::Parity>(0));
serial.open(QIODevice::ReadWrite);
//Tell the serial port connected device to start talking
//--------------------------------------
const char init[] = { 0x0d, 0x0d, 0x0d };
serial.write(init, sizeof(init));
const char* cmd = "mavlink stop\n";
serial.write(cmd, strlen(cmd));
serial.write(init, 2);
cmd = "uorb start";
serial.write(cmd, strlen(cmd));
serial.write(init, 2);
cmd = "sh /etc/init.d/rc.usb\n";
serial.write(cmd, strlen(cmd));
serial.write(init, 4);
serial.waitForBytesWritten(100);
int i = 0;
int j = 0;
forever
{
//Write test data out
//-----------------------------
QByteArray test(2000, 't');
serial.write(test);
bool check = serial.waitForBytesWritten(100);
if (!check)
{
qDebug() << "FAIL: " << j++;
}
if (serial.waitForReadyRead(20))
{
QByteArray responseData = serial.readAll();
while (serial.waitForReadyRead(10))
responseData += serial.readAll();
QString response(responseData);
qDebug() << response;
}
QThread::msleep(20);
//Print memory usage
//---------------------------------------------------
if (i++ % 10 == 0)
{
PROCESS_MEMORY_COUNTERS memcount;
if (!GetProcessMemoryInfo(GetCurrentProcess(), &memcount, sizeof(memcount))) return;
qDebug()<<"----------------------------" << memcount.WorkingSetSize / 1024 << "KB memory used";
}
} // end foever
qDebug() << "Exiting forever loop";
}
用一个简单的 main.cpp 作为:
#include <QApplication>
#include "masterthread.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MasterThread thread;
thread.start();
return app.exec();
}
但内存使用量不断增加,就像每小时 5~10MB 一样,好像有一些泄漏。 该设备应该连接数天和数周......
我在这里做错了什么?我在Qt5.6 windows7调试
【问题讨论】:
-
如果你在一个带有Qt消息循环的线程中运行,那么你可以在
QThread::msleep(20);之前调用QCoreApplication::processEvents(); -
@evilruff 如果某些 Qt 对象在内部使用
deleteLater()或者其他一些依赖事件循环的机制,我可以看到它导致这种行为。我不太了解 Qt,无法准确知道哪些对象依赖于事件循环,哪些不依赖,但如果您有更多经验,请随时分享您的想法。 -
例如,processEvents 将防止此代码受到 Qt 5.5 中的此错误的影响 bugreports.qt.io/browse/QTBUG-48653
-
@Nyaruko 它似乎仍然在内部使用其他东西,例如带有QTimer 的异步信号,这可能仍然可以解释内存,这只是一个例子。你是说即使偶尔调用
QCoreApplication::processEvents();,明显的内存泄漏仍然存在? -
绝对没有理由通过重新实现线程来实现此代码。重构:将其全部放入
QObject,forever部分属于从零超时计时器调用的槽/函子,然后摆脱waitFor并使用信号/槽连接到QIODevice信号。这将导致更清洁、更高效、声明式的代码。请参阅例如this answer 或 that answer 获取灵感。