首页 > 代码库 > 第73课 Qt中的多线程编程
第73课 Qt中的多线程编程
1. QThread类
(1)QThread是一个跨平台的多线程解决方案
(2)QThread以简洁易用的方式实现多线程编程
2. QThread中的关键成员函数
(1)virtual void run() :线程函数,用于定义线程功能(执行流)。
(2)void start():启动函数,将线程入口地址设置为run函数。启动线程,新线程开始执行run函数。
(3)int exec():进入事件循环,直至调用exit()。返回线程退出事件循环的返回码。
(4)void terminate():强制结束线程(不推荐)。
【编程实验】多线程编程初探
//main.cpp
#include <QCoreApplication> #include <QThread> #include <QtDebug> class MyThread : public QThread { protected: //线程函数 void run() { qDebug() << objectName() << " : " << "run() begin"; for(int i=0; i<5; i++) { qDebug() << objectName() << " : " << i; sleep(1); } qDebug() << objectName() << " : " << "run() end"; } }; int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); qDebug() << "main() begin"; MyThread t1; t1.setObjectName("t1"); t1.start(); MyThread t2; t2.setObjectName("t2"); t2.start(); for(int i=0; i<100000; i++) { for(int j=0; j<10000; j++) { } } qDebug() << "main() end"; return a.exec(); }
3. 线程对象和线程的生命周期
(1)线程对象的生命期
①线程对象指的是由QThread类定义的一个对象,是一个Qt对象。其生命周期与一般的Qt对象具有相同的特点。
②每个Qt对象都关联唯一一个线程环境,对象有明确的线程属性。当一个对象在某线程中,这就和该线程建立血缘关系,这种关系会一直保持到它死去或者被moveToThread到另一个线程中。
(2)线程的生命期
(3)线程对象和线程的关系
①QThread类的“线程对象”能够开启新的线程,但它本身所处的线程与新线程不是同一个线程。线程对象和线程是两个不同的概念。
②线程对象的生命周期必须≥由该对象创建出来的线程的生命周期。线程对象先出生,线程后出生,线程先死亡,线程对象后死亡。(这个设计原则对于所有用面向对象封装线程的平台都适用)
③不同线程间的对象之间不能发展成为父子关系,因为线程这种父子关系随时可能因线程的终止而终止,具有不可预见性。这也告诉我们不要在线程对象的run()函数中创建新的局部对象,并将this指针传递给该新对象作为其parent。因为this指的是线程对象本身,与这个新的局部对象位于两个不同的线程中。
4. 线程的终止
(1)暴力终止:调用terminate()。但特别强调,在工程开发中该函数是禁止使用的!terminate会使得操作系统暴力终止线程,而不会才考虑数据完整性,资源释放等问题。
(2)优雅终止线程的解决方案
①run()函数执行结束是优雅终止线程的唯一方式
②在线程类中增加标志变量m_toStop(volatile bool)
③通过m_toStop的值判断是否需要从run()函数返回。
【编程实验】优雅的线程控制
//main.cpp
5. 小结
(1)QThread是一个跨平台的多线程解决方案
(2)QThread以简洁易用的方式实现多线程编程。
(3)void run()函数用于实现线程执行体。
(4)void start()启动线程并执行run()函数。
(5)工程中禁用void terminate()函数结束线程。
第73课 Qt中的多线程编程