一、功能说明
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 <QMainWindow>
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 <QDebug>
#include <QThread>
#include <QtConcurrent>
#include <QFuture>
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<void> ef1 = QtConcurrent::run(func1);
ef1.waitForFinished(); //阻塞等待
//带参数
QFuture<void> ef2 = QtConcurrent::run(func2, QString("sss"));
ef2.waitForFinished(); //阻塞等待
//带返回值
QFuture<int> 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<void> mf1 = QtConcurrent::run(this,&MainWindow::myFunc1);
mf1.waitForFinished(); //阻塞等待
//带参数
QFuture<void> mf2 = QtConcurrent::run(this,&MainWindow::myFunc2, QString("ccc"));
mf2.waitForFinished(); //阻塞等待
//带返回值
QFuture<int> mf3 = QtConcurrent::run(this,&MainWindow::myFunc3, 2 ,3);
mf3.waitForFinished(); //阻塞等待
qDebug() << "mf3"<< QThread::currentThreadId() << mf3.result() << endl;
//同时调用myFunc4函数5次,并打印返回结果
QList< QFuture<int> > 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来区分不同的线程