一、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(); //优雅的结束线程
}
转载于:https://blog.51cto.com/whylinux/1917910