1. 程式人生 > 其它 >QT從入門到入土(四)——多執行緒(QtConcurrent::run())

QT從入門到入土(四)——多執行緒(QtConcurrent::run())

引言

在前面對Qt多執行緒(QThread)做了詳細的分析:QT從入門到入土(四)——多執行緒(QThread) - 唯有自己強大 - 部落格園 (cnblogs.com)

但是最近在做專案時候,要將一個函式單獨執行在另一個執行緒中,並且這個函式是私有函式,用到的資料也是私有資料,不能通過其他類訪問,這樣怎麼辦?如何在Qt中的當前類建立執行緒?


最簡單的多執行緒QtConcurrent::run()

  • 其函式原型如下:
QFuture<T> QtConcurrent::run(Function function, ...)
QFuture<T> QtConcurrent::run(QThreadPool *pool, Function function, ...)

引數function需要外部函式:(或者lambda函式),後面也可跟外部函式的引數。

extern void func(QString str);

QtConcurrent :: run()也接受指向成員函式的指標。第一個引數必須是一個const引用或一個指向該類例項的指標。const成員函式一般傳遞 常量引用 (const reference),而非常量成員函式一般傳遞 指標 (pointer)

  • 在VS環境中需要引用:#include"QtConcurrent/qtconcurrentrun.h"

簡單的說,QtConcurrent::run()函式會在一個單獨的執行緒中執行,並且該執行緒取自全域性QThreadPool,該函式的返回值通過QFuture API提供。
請注意:該函式可能不會立即執行; 函式只有在執行緒可用時才會執行。通過QtConcurrent::run()返回的QFuture不支援取消、暫停,返回的QFuture只能用於查詢函式的執行/完成狀態和返回值。

  • 例項:實現多執行緒耗時操作(呼叫成員函式)

在主程式threadtest.h中宣告成員函式(並新增引用)

#include <QtWidgets/QMainWindow>
#include "ui_threadtest.h"
#include"workThread.h"
#include"qthread.h"
#include"QtConcurrent/qtconcurrentrun.h"//QtConcurrent引用
#pragma execution_character_set("utf-8")
class Threadtest : public QMainWindow
{
    Q_OBJECT

public: Threadtest(QWidget *parent = Q_NULLPTR); private: Ui::ThreadtestClass ui; void work();//成員函式 };

在主程式threadtest.cpp中呼叫成員函式

#include "threadtest.h"
#include"qdebug.h"

Threadtest::Threadtest(QWidget* parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);
    connect(ui.btn_start, &QPushButton::clicked, [=]()
        {
//將成員函式放入引數中(成員函式需要引用指標) QtConcurrent::run(
this, &Threadtest::work); }); } void Threadtest::work() { qDebug() << "子執行緒執行:" << QThread::currentThreadId(); QThread::sleep(5); qDebug() << "子執行緒結束:" << QThread::currentThreadId(); }

點選按鈕即可觸發子執行緒執行。

  • 例項:實現多執行緒耗時操作(呼叫外部函式,帶引數)

在主程式threadtest.h中宣告外部函式

#include <QtWidgets/QMainWindow>
#include "ui_threadtest.h"
#include"workThread.h"
#include"qthread.h"
#include"QtConcurrent/qtconcurrentrun.h"//QtConcurrent引用
#pragma execution_character_set("utf-8")
class Threadtest : public QMainWindow
{
    Q_OBJECT

public:
    Threadtest(QWidget *parent = Q_NULLPTR);  
private:
    Ui::ThreadtestClass ui;
  
};
extern void func(QString str);//外部函式

在主程式threadtest.cpp中呼叫外部函式

#include "threadtest.h"
#include"qdebug.h"

Threadtest::Threadtest(QWidget* parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);
    connect(ui.btn_start, &QPushButton::clicked, [=]()
        {
            QtConcurrent::run(func,QString("extern"));
        });
}
 void func(QString str)
{
    qDebug() << "子執行緒執行:" << QThread::currentThreadId()<< str;
    QThread::sleep(5);
    qDebug() << "子執行緒結束:" << QThread::currentThreadId()<< str;
}