[Qt C++] QThread的正确用法


多线程探究


        不知不觉,从对线程一无所知,到接触了java(实现runnable接口),linux(调用pthread_create创建一个线程,做一些事情),C++ STL中的多线程(直接新建一个进程,做一些事情)。他们处理多线程的方法主要就是两种,要么是“继承”一个线程,要么是直接创建一个线程,不管如何,这个线程都是主进程的一个子对象。

       后来为了保证计算时页面不卡顿,需要接触到Qt的多线程。Qt提供了一个qthread,它需要我们重写run()函数,这和java的思路是很接近的。java是通过接口实现的,但C++没有接口,只有多继承(因为大部分时候我们的主进程是继承自QWidget或者QMainWindow的),多继承是一个破事很多的东西,所以不希望涉及。


      考虑另外一种可能性,直接在主进程中创建一个子进程,这将让我们把QThread设计为主类的一个内部类。但是事实上我们知道内部类和外部类是没有任何关系的,内部类无法访问外部类的对象(哪怕是Public的——因为虽然是public的,但是内部类一般不会具有外部类的实例,无法调用!),这是很糟糕的一件事情,强行把内部类设为友元类也无法完成一些复杂的外部调用;又或者,如果在构造QThread时就把一些必要的参数传进去(极端一点把外部类自己传进去就好了,作为一个对象注入),不得不说这种设计实在是太烂了。


QThread


     后来有一天突然意识到,QThread并不是希望你去继承它,或者是把它作为一个内部类。我们应当先完成一个”线程调度器"类,让这个类来做所有和调度相关的事情。在包含关系中,这个类是最外层的,它把需要调度的类作为自己的子对象。

     例子(一)

    如果你只需要处理一个用于计算的线程的话,这个类可以直接继承自QThread,把原来的主进程所在的类作为子对象, 然后在run()中写你的计算,在合适的时机调用this->start();


thread.h

#ifndef THREAD_H
#define THREAD_H

#include 

class thread:public QThread
{
    Q_OBJECT
private:
    ....
public:
    thread();
protected:
    void run();
private slots:
    void handle();
signals:
};


#endif // THREAD_H


thread.cpp

#include "thread.h"

thread::thread()
{
    //做主线程的工作,包括创建你的窗口,并connect某个signal到槽函数handle()上,以触发次线程的计算
}


void thread::handle()
{
    this->start();//做好预处理后调用计算部分,注意计算部分不能有对UI的操作!如果有的话,请发射一个信号通知主线程修改
}

void thread::run()
{
    //请在这里执行你的计算操作!!!
}

    例子(二)


    如果你需要处理多个线程,那么你可以在这个类里创建多个Qthread实例,指挥它们做不同的事情。

     

class threadA : QThread
{
    Q_OJBECT
protected:
    void run();
public:
    threadA();
}

class threadB : QThread
{
    Q_OBJECT
protected:
    void run();
public:
    threadB();
}
.....

class handleThread : QObject
{
    Q_OBJECT
private:
    ThreadA* threadA;
    ThreadB* threadB;
public:
    handleThread();
}

你可能感兴趣的:(Qt)