main.cpp中:
#include <QCoreApplication>
#include <QtCore>
#include "myobject.h"
QThread* cThread;
MyObject* cObject;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
cThread = new QThread();
cObject = new MyObject();
cObject->moveToThread(cThread);
QObject::connect(cThread, SIGNAL(started()),
cObject, SLOT(doWork()));
QObject::connect(cThread, SIGNAL(finished()),
cThread, SLOT(deleteLater()));
QObject::connect(cThread, SIGNAL(finished()),
cObject, SLOT(deleteLater()));
cThread->start();
return a.exec();
}
myobject.cpp:
#include "myobject.h"
MyObject::MyObject(QObject *parent) :
QObject(parent)
{
}
void MyObject::doWork()
{
qDebug() << "Hi";
QThread::currentThread()->quit();
return;
}
myobject.h:
#ifndef MYOBJECT_H
#define MYOBJECT_H
#include <QtCore>
class MyObject : public QObject
{
Q_OBJECT
public:
explicit MyObject(QObject *parent = 0);
signals:
public slots:
void doWork();
};
#endif // MYOBJECT_H
显然,根据:https://stackoverflow.com/a/16062717,存在内存泄漏,但我该如何解决?我想我必须返回事件循环然后调用退出?但问题是我无法访问事件循环。
答案 0 :(得分:1)
没有内存泄漏。如果你坚持object model和object trees and ownership,Qt会正确清理。我也喜欢关注documented examples。
以下是您引用的示例,deleteLater()
上添加了观察结果。
的main.cpp
#include <QCoreApplication>
#include <QtCore>
#include <QThread>
class MyThread : public QThread
{
Q_OBJECT
public slots:
void deleteLater()
{
qDebug() << Q_FUNC_INFO;
QThread::deleteLater();
}
};
class MyObject : public QObject
{
Q_OBJECT
public:
explicit MyObject(QObject *parent = 0){}
signals:
public slots:
void deleteLater()
{
qDebug() << Q_FUNC_INFO;
QObject::deleteLater();
}
void doWork()
{
qDebug() << "Hi";
QThread::currentThread()->quit(); // It is supposed to stop here, but it doesn't.
return;
for (int i = 0; i < 1000000; i++) {
qDebug() << i;
}
}
};
QThread* cThread;
MyObject* cObject;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
cThread = new MyThread();
cObject = new MyObject();
cObject->moveToThread(cThread);
QObject::connect(cThread, SIGNAL(started()),
cObject, SLOT(doWork()));
QObject::connect(cThread, SIGNAL(finished()),
cThread, SLOT(deleteLater()));
QObject::connect(cThread, SIGNAL(finished()),
cObject, SLOT(deleteLater()));
cThread->start();
return a.exec();
}
输出:
Hi
void __thiscall MyObject::deleteLater(void)
void __thiscall MyThread::deleteLater(void)
希望有所帮助。
答案 1 :(得分:0)
根据standard This function does nothing if the thread does not have an event loop.
,您在(第二个)主题中没有事件循环。尝试调试代码?
试试这个:
的main.cpp
#include <QCoreApplication>
#include <QtCore>
// #include "myobject.h"
// QThread* cThread;
// MyObject* cObject;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// cThread = new QThread();
// cObject = new MyObject();
// cObject->moveToThread(cThread);
// QObject::connect(cThread, SIGNAL(started()),
// cObject, SLOT(doWork()));
// QObject::connect(cThread, SIGNAL(finished()),
// cThread, SLOT(deleteLater()));
// QObject::connect(cThread, SIGNAL(finished()),
// cObject, SLOT(deleteLater()));
// cThread->start();
return a.exec();
}
并查看是否会返回。
没有内存泄漏,因为你的doWork返回正常,删除是由a.exec()内的main-loop-event完成的。但是a.exec()永远不会返回。你必须通过QCoreApplication::quit();
终止你的申请(但不是在线程中,因为你终止整个应用程序)。
您可以在tutorial。
中阅读答案 2 :(得分:0)
我是链接上的海报。事实上,默认连接没有内存泄漏。通过继承deleteLater和析构函数(如@phyatt),您获得了:
Hi
void MyObject::deleteLater()
virtual MyObject::~MyObject() Being deleted
void MyThread::deleteLater()
virtual MyThread::~MyThread() Being deleted
但是如果您在连接中使用Qt::QueueConnection
,则获得:
Hi
void MyThread::deleteLater()
virtual MyThread::~MyThread() Being deleted
对象cObject
被泄露了。
当线程 有效地 退出时,它没有记录。所以我不能争论这种行为是否总是一样的。一种可能性是使线程启动器负责执行清理工作。例如:
void cleanup(){
cThread->exit();
cThread->wait();
delete cThread;
delete cObject;
}
要完成整理,您无需使用此代码修复任何内容。