一、Qt中通过QThread直接支持多线程
1、QThread是一个跨平台的多线程解决方案
2、QThread以简洁易用的方式实现多线程编程
注意:1、Qt中的线程以对象的形式被创建和使用
2、每一个线程对应着一个QThread对象
QThread这个类,是一个线程父类,我们需要继承这个QThread类。
QThread类,提供了一组成员函数。一个线程是以一个对象的形式来表现出来,所以说,我们创建一个
线程的时候,实际上就是创建了一个这个QThread线程类的对象
一个线程对应一个QThread对象
二、QThread中的关键成员函数
1、void run()
线程体函数,用于定义线程功能(执行流),是线程的入口函数。
2、void start()
启动函数,在操作系统中真正创建出一个线程后,将线程入口地址设置为run函数
3、void terminate()
强制结束线程(不推荐)
三、自定义一个线程类
class MyThread : public QThread { protected: //保护,被保护的成员函数,不能直接被外界访问,但是可以被子类直接访问 void run() //重写QThread类中的run成员函数,来实现我们线程体逻辑 { for ( int i = 0; i < 5; i++) { qDebug() << objectName() <<i; //objectName,当前对象的名字 sleep(1); //这个sleep函数,是QThread类里面的一个静态的成员函数 } } }; int main(int argc, char *argv[]) { MyThread t; //创建子线程 t.setobjectName("t"); //设置t对象的名字为t t.start(); //启动子线程 MyThread tt; //又创建了一个线程 tt.setobjectName("tt"); tt.start(); }
可以说是三个线程上面的,因为还包含了主线程,三个线程是并行执行的。宏观上。
注意:上面代码,主线程将先于子线程结束,所有子线程全部结束后,进程结束。
一个进程的结束,要等待内部的所有线程都结束后,才会结束。
四、线程的生命周期
1、用线程类创建一个对象时,可以说我们已经创建一个线程了,被创建的线程对象
调用start成员函数后,线程开始运行,运行的是run成员函数体,该线程参与操作
系统的调度,操作系统给每一个线程一定的时间片时间去执行,时间片到了当前线程
停止运行,其他线程运行它的时间片,如此调度,所以从单核cpu的角度看,微观看,线程
是顺序执行,由操作系统切换每个线程的执行。线程的非正常死亡之一是因terminate()
成员函数导致,所以terminate成员函数不推荐使用,因为不会考虑数据的完整性,
会暴力的杀死线程,可能会导致资源没有被释放,数据不完整等,所以在工程中
禁止调用。
2、不调用terminate()成员函数去结束一个线程,那如何优雅的结束一个线程的生命期呢?
(1)解决方案思路:
run()函数执行结束是优雅终止线程的唯一方式,因为是线程的自然死亡,run成员函数被执行完了
run成员函数被正常的返回了,这种叫做正常的死亡,所以在线程类中增加一个标志变量m_toStop(volatile bool),通过m_toStop的值判断是否需要从run()函数返回。run函数返回,为优雅
的结束线程 。volatile关键字必须去修饰这个标志变量,不需要编译去优化,而是我们每次都会去内存中去取这个值,值是易变的,所以加volatile。
3、代码如下
class MyThread :public QThread { protected: volatile bool m_toStop; void run(); public: MyThread() { m_toStop = false; } void stop() { m_toStop = true; } }; void MyThread::run() { while (!m_toStop) { } }
上面的代码,如果run函数中的while循环中,判断到了m_toStop变量值为true了,
则会不执行while循环,跳出while循环,向下执行后,run函数就会自己返回,这个
方法是工程中,结束一个线程执行的一个很好的方法,标准优雅的去结束一个线程。
class MyThread :public QThread { protected: volatile bool m_toStop; void run() { int *p = new int[10000]; //申请了10000*int大小的堆空间让p指向 for ( int i = 0; !m_toStop && (i < 10); i++ ) { p[i] = i * i; sleep(1); } delete[] p; } public: MyThread() { m_toStop = false; } void stop() { m_toStop = true; } };
int main(void)
{
MyThread t;
t.start();
Sleep(5000);
t.stop(); //优雅的结束线程
}
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。