多线程技术

说明

  • QT支持以下四种方式实现多线程程序。

QThread:低级接口并且支持可选的时间循环

  • QThread是多线程编程的基础类,QThread实例就是线程实例。
  • QThread支持两种使用方式:
  1. 可以直接实例化QThread。
  2. 可以继承QThread,实例其子类。

实例化QThread(moveToThread方式)

  • 该方式是官方推荐使用方式,实例化QThread提供了一个并行的事件循环,允许在其它线程通过信号的方式调用其内部函数。
  • 使用流程:
  1. 定义一个继承QObject的类,如下:
* 头文件
class ThreadFunction : public QObject
{
    Q_OBJECT
public:
    Thread();
    ~thread();
    
    void fun(int a);
};

* cpp文件
...
void ThreadFunction::fun(int a){
    ....
}
  1. 实例化QThread和将ThreadFunction对象moveToThread,如下:
QThread *Thread_Test = new QThread;
ThreadFunction *thread_class = new ThreadFunction;
thread_class->moveToThread(Thread_Test);
Thread_Test->start(); //开启线程
  1. 通过信号并行执行
connect(this,&MainWindow::ToThread, thread_class,&ThreadFunction::fun); //ToThread是定义的信号
emit ToThread(1);

继承QThread,实例其子类

  • 子类化QThread允许程序在启动事件循环之前初始化新线程,但是没有事件循环,适合于需要循环执行的任务。
  • 使用流程:
  1. 继承QThread类,并重写run函数,如下:
class TestThread : public QThread
{
    Q_OBJECT
public:
    TestThread(const QString &s, QObject *parent);

protected:
    void run() override;

private:
    ....;
};

* cpp
...
void TestThread::run(){
    while(1){
        ....;
    }
}
  1. 创建线程并启动
TestThread *t = new TestThread("test", this);
t->start();

QThreadPool + QRunnable : 重复使用的线程

  • 为了减少频繁的创建和销毁线程的开销,可以使用QThreadPool(线程池)+ QRunnable(任务实例)的方式。
  • 使用流程:
  1. 定义QRunnable子类,并重写run函数,如下:
class LoginRunnable: public QRunnable
{
public:
    LoginRequestRunnable();

protected:
    void run() override;
};

void LoginRunnable::run(){
    ....;
}
  1. 创建QThreadPool实例或者使用全局线程池
  • 全局线程池会根据CPU的核心数自动维护最佳线程数。
QThreadPool::globalInstance();
  1. 创建QRunnable子类实例,并放入QThreadPool中执行。
LoginRunnable *login = new LoginRunnable();

QThreadPool::globalInstance()->start(login);

线程交互

  • 使用线程池的方式,如果需要和其它线程交互,有两种方式,如下:
  1. QMetaObject::invokeMethod方式
* 构建QRunnable子类对象时传入object对象
class QMyRunnable : public QRunnable
{
public:
    QMyRunnable(QObject* obj);

protected:
    void run();
    
private:
    QObject* obj;
};
* 定义信号接收槽函数
class Widget : public QWidget {
    Q_OBJECT
public:
    Widget(QWidget *parent = 0);
    ~Widget();
private slots:
    void Update_Result(QString);

private:
    ....;
};
QMyRunnable *login = new QMyRunnable(this)
* 在QRunnable子类对象run函数中执行QMetaObject::invokeMethod
void QMyRunnable::run()
{
    ....;
  QString str = QString("%1+%2=%3").arg(1).arg(1).arg(1+1);  
  QMetaObject::invokeMethod(obj,"Update_Result",Q_ARG(QString,str));
}
  1. 信号/槽方式
  • 定义任务类既继承QRunnable也继承QObject,如下:
class QMyRunnable : public QRunnable, public QObject
{
    Q_OBJECT
public:
    QMyRunnable(QObject* obj);

protected:
    void run();
    
private:
    QObject* obj;
};
  • 即可通过信号/槽的方式进行交互。

Concurrent : 高级接口

  • 待研究

WorkerScript : QML编程中使用的线程

  • 待研究

注意

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值