第83课 - 另一种创建线程的方式

版权声明:课程笔记内容整理于狄泰软件 https://blog.csdn.net/qq_39654127/article/details/82018872

1、另一种创建线程的方式 

历史的痕迹

class QThread : public QObject
{
    //...
protected: 
    virtual void run()= 0; 
    
    /*
     * 面向对象程序设计实践的早期,工程中
     * 习惯于通过继承的方式扩展系统的功能。
    */
    
} 

 现代软件架构技术 

      参考准则: 

             尽量使用组合的方式实现系统功能 

             代码中仅体现需求中的继承关系 

 

                                  除了重写的run不同,其它接口完全相同

结论

     -通过继承的方式实现多线程没有任何实际意义

     -QThread对应于操作系统中的线程 

     -QThread用于充当一个线程操作的集合 

     -应该提供灵活的方式指定线程入口函数 

     -尽量避免重写void run() 

QThread类的改进 

class QThread : public QObject
{
    //...
    
protected: 
    virtual void run() //新版本QT
    {
        (void)exec(); //默认开启事件循环
    }
       
    //...
} 

如何灵活的指定一个线程对象的线程入口函数? 

 

解决方案-信号与槽 

       1. 在类中定义一个槽函数void tmain()作为线程入口函数 

       2. 在类中定义一个QThread成员对象m_thread 

       3. 改变当前对象的线程依附性到m_thread 

       4 连接m_threadstart()信号到tmain() 

2、编程实验 

另一种创建线程的方式   83-1.pro 

AnotherThread.h

#ifndef ANOTHERTHREAD_H
#define ANOTHERTHREAD_H

#include <QObject>
#include <QThread>

class AnotherThread : public QObject
{
    Q_OBJECT

    QThread m_thread;
protected slots:
    void tmain();//线程入口函数
public:
    explicit AnotherThread(QObject *parent = 0);
    void start();
    void terminate();
    void exit(int c);
    ~AnotherThread();
    
};

#endif // ANOTHERTHREAD_H

AnotherThread.cpp

#include "AnotherThread.h"
#include <QDebug>

AnotherThread::AnotherThread(QObject *parent) :
    QObject(parent)
{
    moveToThread(&m_thread);

    connect(&m_thread, SIGNAL(started()), this, SLOT(tmain()));
}

void AnotherThread::tmain()
{
    qDebug() << "void AnotherThread::tmain() tid = " << QThread::currentThreadId();

    for(int i=0; i<10; i++)
    {
        qDebug() << "void AnotherThread::tmain() i = " << i;
    }

    qDebug() << "void AnotherThread::tmain() end";

    m_thread.quit();
}

void AnotherThread::start()
{
    m_thread.start();//m_thread线程开启,定义的tmain函数被调用(run函数也被调用,开启事件循环)
}

void AnotherThread::terminate()
{
    m_thread.terminate();
}

void AnotherThread::exit(int c)
{
    m_thread.exit(c);
}

AnotherThread::~AnotherThread()
{
    m_thread.wait();//同步设计,保证线程生命周期大于对象声明周期
}

main.cpp

#include <QtCore/QCoreApplication>
#include <QDebug>
#include <QThread>
#include "AnotherThread.h"

void test()
{
    AnotherThread at;

    at.start();
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    qDebug() << "main() tid = " << QThread::currentThreadId();

    test();
    
    return a.exec();
}

                                   灵活的指定tmain为线程入口函数

3、小结 

早期的Qt版本只能通过继承的方式创建线桯 

现代软件技术提倡以组合的方式代替继承 

QThread应该作为线程的操作集合而使用 

可以通过信号与槽的机制灵活指定线程入口函数 

猜你喜欢

转载自blog.csdn.net/qq_39654127/article/details/82018872