一、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()

强制结束线程(不推荐)


三、自定义一个线程类

classMyThread:publicQThread{protected://保护,被保护的成员函数,不能直接被外界访问,但是可以被子类直接访问voidrun()//重写QThread类中的run成员函数,来实现我们线程体逻辑{for(inti=0;i<5;i++){qDebug()<<objectName()<<i;//objectName,当前对象的名字sleep(1);//这个sleep函数,是QThread类里面的一个静态的成员函数}}};intmain(intargc,char*argv[]){MyThreadt;//创建子线程t.setobjectName("t");//设置t对象的名字为tt.start();//启动子线程MyThreadtt;//又创建了一个线程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、代码如下

classMyThread:publicQThread{protected:volatileboolm_toStop;voidrun();public:MyThread(){m_toStop=false;}voidstop(){m_toStop=true;}};voidMyThread::run(){while(!m_toStop){}}

上面的代码,如果run函数中的while循环中,判断到了m_toStop变量值为true了,

则会不执行while循环,跳出while循环,向下执行后,run函数就会自己返回,这个

方法是工程中,结束一个线程执行的一个很好的方法,标准优雅的去结束一个线程。

classMyThread:publicQThread{protected:volatileboolm_toStop;voidrun(){int*p=newint[10000];//申请了10000*int大小的堆空间让p指向for(inti=0;!m_toStop&&(i<10);i++){p[i]=i*i;sleep(1);}delete[]p;}public:MyThread(){m_toStop=false;}voidstop(){m_toStop=true;}};

int main(void)

{

MyThread t;


t.start();


Sleep(5000);

t.stop(); //优雅的结束线程


}