1. QThread线程示例
下面是一个基本的线程的相关头文件和源文件。
#ifndef TEST1THREAD_H
#define TEST1THREAD_H
#include <QThread>
class Test1Thread : public QThread
{
public:
Test1Thread();
~Test1Thread();
protected:
void run();
};
#endif // TEST1THREAD_H
#include "Test1Thread.h"
#include <QDebug>
Test1Thread::Test1Thread()
{
qDebug() << "Test1Thread::Test1Thread()";
}
Test1Thread::~Test1Thread()
{
qDebug() << "Test1Thread::~Test1Thread()";
}
void Test1Thread::run()
{
qDebug() << "Test1Thread::run()";
}
上面的三个qDebug内容完全能够监控执行到哪一步了以及执行的情况。
下面展示两个错误的操作方法。
1.0 基本的需求
需要在触发一个方法的时候,在这个方法里面执行相关的线程操作。
1.1 直接在执行的方法里面创建对象
如下的代码里面是对这个线程的创建和执行:
void MainWindow::on_pushButton_clicked()
{
Test1Thread t1t;
t1t.start();
}
执行的结果如下:
Test1Thread::Test1Thread()
Test1Thread::~Test1Thread()
Test1Thread::run()
QThread: Destroyed while thread is still running
QMutex: destroying locked mutex
出现这个问题的原因是,这个线程对象的声明周期是触发按键的这个方法里面,在完成这里面的代码后,会对这里面的内容进行析构,但是这个时候,线程上的内容会被强制清理,然后就出现了下面的错误;换一句话说,就是没有正确释放线程。
1.2 在需要执行的方法里面new一个对象
代码如下:
void MainWindow::on_pushButton_clicked()
{
Test1Thread *t1t = new Test1Thread;
t1t->start();
}
执行的结果如下:
Test1Thread::Test1Thread()
Test1Thread::run()
这样的话,看似可以正常执行,但是造成了内容的泄露,开辟的新的对象一直在内存里面,不能将其析构。
2 较好的一个解决方案
有一个比较好的方法,如下:
void MainWindow::on_pushButton_clicked()
{
Test1Thread *t1t = new Test1Thread;
connect(t1t,SIGNAL(finished()),t1t,SLOT(deleteLater()));
t1t->start();
}
执行的结果如下:
Test1Thread::Test1Thread()
Test1Thread::run()
Test1Thread::~Test1Thread()
这样就已经正常执行了结果。
这是由于线程run()方法内的内容执行完成之后会触发finished()方法,根据在触发这个信号之后将其在一会儿后删除。然后就能正常完成这个线程的执行和析构。