18、Qt线程(三):使用QtConCurrent模块

一、功能说明

1、使用QtConCurrent并发模块的run()函数方式实现多线程

2、点击“开始”按钮启动子线程;

3、run()分别调用外部函数、Lamdba表达式和成员函数

二、项目创建

1、新建Qt Widgets Application应用,名称为ConCurrent,基类选择QMainWindow;

2、MainWindow.ui中放入一个Push Button按钮,第一个text改为“开始”,objectNme改为startPushButton;

3、注:

①QtConcurrent::run()函数会在一个单独的线程中执行,并且该线程取自全局线程池QThreadPool,该函数的返回值通过QFuture API提供。

②该函数可能不会立即运行; 函数只有在线程可用时才会运行。

③通过QtConcurrent::run()返回的QFuture不支持取消、暂停,返回的QFuture只能用于查询函数的运行/完成状态和返回值。

④使用waitForFinished()函数,第一个运行完成,才会运行第二个,所以输出的线程id是一样的。

三、代码展示

1、ConCurrent.pro

在ConCurrent.pro中添加一行QT += concurrent

#-------------------------------------------------
#
# Project created by QtCreator 2023-09-27T09:05:16
#
#-------------------------------------------------

QT += core gui
QT += concurrent

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = ConCurrent
TEMPLATE = app

# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0

CONFIG += c++11

SOURCES += \
main.cpp \
mainwindow.cpp

HEADERS += \
mainwindow.h

FORMS += \
mainwindow.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

2、mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void on_startPushButton_clicked();

    void myFunc1();
    void myFunc2(QString str);
    int myFunc3(int i, int j);
    int myFunc4(int i, int j);

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

3、mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include 
#include 
#include 
#include 

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void func1()
{
    qDebug() << "func1" << QThread::currentThreadId();
}

void func2(QString str)
{
    qDebug() << "func2" << QThread::currentThreadId() << str ;
}

int func3(int i, int j)
{
    int ret = i + j;
    qDebug() << "func3"<< QThread::currentThreadId() << ret ;
    return ret;
}

void MainWindow::on_startPushButton_clicked()
{
/****************************外部函数************************************/
    //不带参数
    QFuture ef1 = QtConcurrent::run(func1);
    ef1.waitForFinished(); //阻塞等待
    
    //带参数
    QFuture ef2 = QtConcurrent::run(func2, QString("sss"));
    ef2.waitForFinished(); //阻塞等待

    //带返回值
    QFuture ef3 = QtConcurrent::run(func3, 2, 3);
    ef3.waitForFinished(); //阻塞等待
    qDebug() << "ef3"<< QThread::currentThreadId() << ef3.result() << endl;

/****************************Lambda表达式************************************/
    //不带参数
    QFuture < void > lf1 = QtConcurrent::run([=]()
    {
        qDebug() << "lambda1" << QThread::currentThreadId();
    });
    lf1.waitForFinished(); //阻塞等待

    //带参数
    QFuture < void > lf2 = QtConcurrent::run([=](QString str)
    {
        qDebug() << "lambda2" << QThread::currentThreadId() << str;
    }, QString("lfff"));
    lf2.waitForFinished(); //阻塞等待

    //带返回值
    QFuture < int > lf3 = QtConcurrent::run([=](int i, int j)
    {
        qDebug() << "lambda3" << QThread::currentThreadId() << (i+j);
        return (i+j);
    }, 2, 3);
    lf3.waitForFinished(); //阻塞等待
    qDebug() << "lf3"<< QThread::currentThreadId() << lf3.result() << endl;

/****************************成员函数************************************/
    //不带参数
    QFuture mf1 = QtConcurrent::run(this,&MainWindow::myFunc1);
    mf1.waitForFinished(); //阻塞等待
   
     //带参数
    QFuture mf2 = QtConcurrent::run(this,&MainWindow::myFunc2, QString("ccc"));
    mf2.waitForFinished(); //阻塞等待
    
    //带返回值
    QFuture mf3 = QtConcurrent::run(this,&MainWindow::myFunc3, 2 ,3);
    mf3.waitForFinished(); //阻塞等待
    qDebug() << "mf3"<< QThread::currentThreadId() << mf3.result() << endl;

    //同时调用myFunc4函数5次,并打印返回结果
    QList< QFuture > rets;
    for(int i = 0; i < 5; i++)
    {
        rets.append(QtConcurrent::run(this, &MainWindow::myFunc4, i , 2));
    }
    foreach(auto ret, rets)
    {
        qDebug() << ret;
    }
}

void MainWindow::myFunc1()
{
    qDebug() << "myFunc1" << QThread::currentThreadId();
}

void MainWindow::myFunc2(QString str)
{
    qDebug() << "myFunc2" << QThread::currentThreadId() << str;
}

int MainWindow::myFunc3(int i, int j)
{
    qDebug() << "myFunc3" << QThread::currentThreadId() << (i+j);
    return (i+j);
}

int MainWindow::myFunc4(int i, int j)
{
    qDebug() << "myFunc4" << QThread::currentThreadId() << (i+j);
    return (i+j);
}

四、运行测试

先点击开始,输出框输出如下内容,根据线程id来区分不同的线程

18、Qt线程(三):使用QtConCurrent模块_第1张图片

你可能感兴趣的:(Qt小功能,qt)