C++/Qt 多线程

概述

Qt中有多种方式实现多线程,这里主要简单介绍Qt中 moveToThreadQtConcurrent::run 创建线程的方法,以及如何在线程中和Qt界面交互。

Qt中最基础的线程创建方式是使用QThread,即新建一个线程类继承QThread,重写 run() 函数并通过 start() 函数启动线程。因为Qt官方已经不推荐使用这种方式,所以这里不再阐述。

moveToThread

moveToThread 是在QThread的用法基础上扩展出来,其继承于QObject类。即通过继承QObject类并使用 moveToThread 移到一个QThread的对象中。
示例如下:
首先,创建一个继承于QObject的类,定义一个槽函数,即在线程中需要执行的函数;定义一个信号,用于线程完成时通知界面。

//MyThread.h
#include 

class MyThread: public QObject {
    Q_OBJECT
public:
    explicit MyThread(QObject *parent = 0);
    ~MyThread();
signals:
    void Threadfinish(); //线程完成时的信号
public slots:
    void slot_StartMyThread(); //需要在线程中执行的槽函数
};

//MyThread.cpp
#include "MyThread.h"
#include 

MyThread::MyThread(QObject *parent) : QObject(parent) {
}

MyThread::~MyThread(){
}

void MyThread::slot_StartMyThread() {
    //打印线程ID
    qDebug() << "kid " << "threadID : " << QThread::currentThread();

    //...需要执行的内容

    //返回线程完成信号
    emit Threadfinish();
}

主界面(因为是公司项目,这里展示主要的代码):

//.h文件
//类中定义:
public:
    void start_thread(); //开启线程函数
signals:
    void sig_startThread(); //通知子线程的信号
private:
    MyThread* m_myThread; //线程指针
    QThread* subthread;
public slots:
    void slot_finishThread(); //线程完成的槽函数

//.cpp文件
void MainFrameUi::start_thread() {
    qDebug() << "main " << "threadID : " << QThread::currentThread();
    subthread->start(); //开启线程
    emit sig_startThread(); //通过信号通知子线程任务
}

void MainFrameUi::slot_finishThread() {
    //处理线程完成的函数    
    //...
}

//构造函数中初始化,也可以在函数中初始化
subthread = new QThread();
m_myThread= new MyThread();
m_myThread->moveToThread(subthread);
connect(this, SIGNAL(sig_startThread()), m_myThread, SLOT(slot_StartMyThread())); 
connect(m_myThread, SIGNAL(Threadfinish()), this, SLOT(slot_finishThread()));
connect(subthread, &QThread::finished, m_myThread, &QObject::deleteLater);

初始化后,使用 start_thread() 函数开启进程。
subthread = new QThread(); 使用QThread创建一个多线程容器
m_myThread= new MyThread(); 新建自己的线程类
m_myThread->moveToThread(subthread); 将线程类移动到线程容器中
connect(this, SIGNAL(sig_startThread()), m_myThread, SLOT(slot_StartMyThread())); 开始线程信号绑定到子线程中需要执行的槽函数
connect(m_myThread, SIGNAL(Threadfinish()), this, SLOT(slot_finishThread())); 子线程结束信号绑定到主界面的处理线程完成函数
connect(subthread, &QThread::finished, m_myThread, &QObject::deleteLater); subthread线程结束后,让m_myThread销亡

运行结果

main threadID : QThread(0x1393a0920d)
kid threadID : QThread(0x139409cd290)

QtConcurrent::run

QtConcurrent::run是Qt提供了的高级API接口,能够方便快捷的将任务放到子线程中去执行,无需继承任何类,也不需要重写函数,使用非常简单。
既可以执行普通函数,也可以执行类成员函数。
示例如下:
本人使用VS编写Qt,首先在项目Qt设置中勾选Concurrent模块

Qt项目设置

引入头文件 #include
使用QtConcurrent::run将任务放入子线程中

//QFuture QtConcurrent::run(Function function, ...)
QString str = "test";
QFuture fun_res1 = QtConcurrent::run(fun1,str)
//QFuture QtConcurrent::run(QThreadPool *pool, Function function, ...)
QFuture fun_res2 = QtConcurrent::run(this, &MainFrameUi::fun2, str)

第一种,分别传入函数指针和参数;
第二种,第一个参数为一个const引用或一个指向该类实例的指针,第二个参数为该类的成员函数,第三往后为函数的参数。
注:当传入函数的参数大于5个时,则需要将参数定义为结构体,使用结构体传参,否则函数报错。

你可能感兴趣的:(C++/Qt 多线程)