一、线程的生命周期
1、一个工程中的实际
(1)、c++对象有生命周期
(2)、线程也有生命周期
(3)、工程实践中的经验准则要想办法保证:线程对象(QThread对象)的生命周期 > 对应线程的生命周期
问题代码:在栈中定义局部线程对象 t.start()后继承向下执行,然后线程对象销毁,里面的成员变量 i 也销毁,但是run()还未结束,就会操作一个被销毁的对象,程序崩溃
二、同步型线程的设计
1、概念:线程对象主动等待线程生命周期结束后才销毁
2、特点
(1)、同时支持栈和堆中创建线程对象
(2)、对象销毁时确保线程生命周期结束
3、要点:在析构函数中先调用wait()函数,强制等待线程运行结束
4、使用场合:线程生命周期相对较短的情形
三、异步型线程设计
1、概念:线程生命周期结束时通知销毁线程对象
2、特点
(1)、只能在堆中创建线程对象(把构造函数声明为私有,所以要像二阶构造一样定义静态成员函数来创建对象)
(2)、线程对象不能被外界主动销毁(把析构函数声明为私有)
3、要点:
(1)、在run()中最后调用deleteLater ()函数(顾名思义deleteLater()可知只能在堆上创建对象)
(2)、线程体函数主动申请销毁线程对象(向Qt平台申请)
4、使用场合:线程周期不可控,需要长时间运行于后台的情形
int main(int argc, char* argv[]) tid= 0x1c08 void AsynThread::run() tid= 0x2050 void AsynThread::run() i= 0 void AsynThread::run() i= 1 void AsynThread::run() i= 2 void AsynThread::run() end AsynThread::~AsynThread()//调用了析构函数,说明没有内存泄漏
#ifndef MYTHREAD_H #define MYTHREAD_H #include <QThread> class MyThread : public QThread { Q_OBJECT public: explicit MyThread(QObject *parent = 0); signals: public slots: private: void run(); }; #endif // MYTHREAD_H
#include "MyThread.h" #include <QDebug> MyThread::MyThread(QObject *parent) : QThread(parent) { } void MyThread::run() { qDebug() << "void MyThread::run() tid=" << QThread::currentThreadId(); for(int i=0; i<3; i++) { qDebug() << "void MyThread::run() i=" << i; sleep(1); } qDebug() << "void Mythread::run end"; }
#ifndef SYNTHREAD_H #define SYNTHREAD_H #include <QThread> class SynThread : public QThread { Q_OBJECT public: explicit SynThread(QObject *parent = 0); ~SynThread(); private: void run(); }; #endif // SYNTHREAD_H
#include "Synthread.h" #include <QDebug> SynThread::SynThread(QObject *parent) : QThread(parent) { } void SynThread::run() { qDebug() << "void SynThread::run() tid=" << QThread::currentThreadId(); for(int i=0; i<3; i++) { qDebug() << "void MyThread::run() i=" << i; sleep(1); } qDebug() << "void SynThread::run() end"; } SynThread::~SynThread() { wait();//析构函数中等待线程周期结束 qDebug() << "SynThread::~SynThread()"; }
#ifndef ASYNTHREAD_H #define ASYNTHREAD_H #include <QThread> class AsynThread : public QThread { Q_OBJECT public: static AsynThread* NewInstance(QObject *parent=0); private: void run(); explicit AsynThread(QObject *parent = 0);//构造函数和析构函数定义成私有的 ~AsynThread(); }; #endif // ASYNTHREAD_H
#include "AsynThread.h" #include <QDebug> AsynThread::AsynThread(QObject *parent) : QThread(parent) { } AsynThread* AsynThread::NewInstance(QObject *parent) { return new AsynThread(parent); } void AsynThread::run() { qDebug() << "void AsynThread::run() tid=" << QThread::currentThreadId(); for(int i=0; i<3; i++) { qDebug() << "void AsynThread::run() i=" << i; sleep(1); } qDebug() << "void AsynThread::run() end"; deleteLater();//注意要放在最后 } AsynThread::~AsynThread() { qDebug() << "AsynThread::~AsynThread()"; }
#include <QtCore/QCoreApplication> #include "MyThread.h" #include "Synthread.h" #include "AsynThread.h" #include <QDebug> #include <QThread> void mythread() { MyThread t; t.start(); } void Synthread() { SynThread st; st.start(); } void Asynthread() { AsynThread* at = AsynThread::NewInstance(); //AsynThread t;//编译出错,构造函数私有 at->start(); //delete at;//编译出错,析构函数私有 } int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); qDebug() << "int main(int argc, char* argv[]) tid=" << QThread::currentThreadId(); //mythread();//程序崩溃 //Synthread();//同步型线程,正确无误运行 Asynthread(); return a.exec(); }
四、小结
(1)、线程对象的生命周期必须大于对应线程的生命周期
(2)、同步型线程设计---线程生命期较短
(3)、异步型线程设计---线程生命期不可控
(4)、线程类的设计必须适应具体的场合
(5)、没有万能的设计,只有合适的设计