关于QT多线程开发介绍
-
QT下线程的创建方式
Qt中主要有两种创建多线程的方式,一种是直接继承QThread重写run()函数来实现,另外一种是将一个继承于QObject的普通类通过moveToThread()方法移动到一个线程里去。 本文主要是理清如何正确的创建一个线程,和如何正确的退出一个线程。
本文主要记录QThread的普通用法,网上有许多相关资料,如果已经了解可忽视,本文重点介绍线程安全退出的方法。
- 继承QThread重写run()函数线程创建方式
//.h文件
class Mythread:public QThread
{
Q_OBJECT
public:
Mythread(){}
~ Mythread(){}
virtual void run();
/*******************/
};
/****************************/
//.cpp文件
void Mythread::run()
{
while (1)
{
//耗时操作
}
}
- 继承于QObject的普通类通过moveToThread()方法移动到一个线程的创建方式
//.h文件
class Mythread:public QThread
{
Q_OBJECT
public:
Mythread(){}
~ Mythread(){}
virtual void run();
/*******************/
};
class MoveThread:public QObject
{
Q_OBJECT
public:
MoveThread(){}
~MoveThread(){}
};
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
Mythread * m_thread;
MoveThread * m_movethread;
};
//.cpp文件
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
m_thread= new Mythread ();
m_movethread= new MoveThread ();
m_movethread->moveToThread(m_thread);
}
二者创建线程的优缺点和差异在以后文章中会单独列出(关于Qt多线程下信号槽的调用机制及事件循环机制的介绍)
-
QT线程开启和退出
线程开启函数:start()
不应该直接调用run函数,而应该使用**start()**函数
线程退出函数:quit()、exit()、terminate()用于线程终结退出
1.quit()函数告诉线程退出事件循环,让exec()返回0(成功)。等同于调用QThread::exit(0)。如果线程没有事件循环,这个函数什么事也不做。
2.exit()函数通知线程退出事件循环,并且传入一个code值。
调用该函数后,线程退出事件循环,并从QEventLoop::exec()调用中返回。QEventLoop::exec()返回一个returnCode码。一般情况,返回码为0意味着调用成功,非0值代表失败。
注意:和c库同名的函数不一样,调用该函数不返回一个值,它仅仅产生一个停止事件。
3.terminate()函数立即终止一个线程可以使用,但这个函数存在非常不安定因素,不推荐使用
4.线程调用wait()函数可以阻断本身的运行,直到其他的线程完成执行(或者一个指定的时间间隔后)。
- 如何安全退出Qt线程
方法是添加一个bool变量,通过主线程修改这个bool变量来进行终止,但这样有可能引起访问冲突,所以需要加锁联合使用。具体操作如下:
//.h文件
class Mythread:public QThread
{
Q_OBJECT
public:
Mythread();
~Mythread();
virtual void run();
void runstart()
{
isCanRun=true;
}
void runstop()
{
isCanRun=false;
}
bool getcurrentstate()
{
return isCanRun;
}
/**********变量区**********/
protected:
volatile bool isCanRun = false;
public slots:
void stopImmediatelyS1();
private:
static QMutex m_lock; //原子操作锁
/*******************/
};
//.cpp文件
Mythread::Mythread()
{
isCanRun = false;
connect(this,SIGNAL(finished()),this,SLOT(deleteLater()));
}
QMutex Mythread::m_lock; //初始化静态锁
Mythread::~Mythread()
{
}
void Mythread::stopImmediatelyS1()
{
QMutexLocker locker(&m_lock);
isCanRun = false;
}
void Mythread::run()
{
isCanRun = true;
while (isCanRun)
{
//耗时操作
{
QMutexLocker locker(&m_lock);
if(!isCanRun) //设置退出线程
{
return;
}
}
exec();//开启事件循环
}
}
这里是引用:本文是个人开发学习记录,如有差错欢迎大神指点