国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Qt 多線程的幾種實(shí)現(xiàn)方式

這篇具有很好參考價(jià)值的文章主要介紹了Qt 多線程的幾種實(shí)現(xiàn)方式。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

Qt多線程的實(shí)現(xiàn)方式有:

1. 繼承QThread類(lèi),重寫(xiě)run()方法

2. 使用moveToThread將一個(gè)繼承QObject的子類(lèi)移至線程,內(nèi)部槽函數(shù)均在線程中執(zhí)行

3. 使用QThreadPool,搭配QRunnable(線程池)

4. 使用QtConcurrent(線程池)

為什么要用線程池?

創(chuàng)建和銷(xiāo)毀線程需要和OS交互,少量線程影響不大,但是線程數(shù)量太大,勢(shì)必會(huì)影響性能,使用線程池可以減少這種開(kāi)銷(xiāo)。

一、繼承QThread類(lèi),重寫(xiě)run()方法

缺點(diǎn):

  1. 每次新建一個(gè)線程都需要繼承QThread,實(shí)現(xiàn)一個(gè)新類(lèi),使用不太方便。
  2. 要自己進(jìn)行資源管理,線程釋放和刪除。并且頻繁的創(chuàng)建和釋放會(huì)帶來(lái)比較大的內(nèi)存開(kāi)銷(xiāo)。
適用場(chǎng)景:QThread適用于那些常駐內(nèi)存的任務(wù)。

 1 //mythread.h
 2 #ifndef MYTHREAD_H
 3 #define MYTHREAD_H
 4 
 5 #include <QThread>
 6 
 7 class MyThread : public QThread
 8 {
 9 public:
10     MyThread();
11     void stop();
12 
13 protected:
14     void run();
15 
16 private:
17     volatile bool stopped;
18 };
19 
20 #endif // MYTHREAD_H
 1 //mythread.cpp
 2 #include "mythread.h"
 3 #include <QDebug>
 4 #include <QString>
 5 
 6 MyThread::MyThread()
 7 {
 8     stopped = false;
 9 }
10 
11 
12 
13 void MyThread::stop()
14 {
15     stopped = true;
16 }
17 
18 
19 
20 void MyThread::run()
21 {
22     qreal i = 0;
23 
24     while( !stopped )
25     {
26         qDebug() << QString("in MyThread: %1").arg(i);
27         sleep(1);
28         i++;
29     }
30     stopped = false;
31 }
 1 //widget.h
 2 #ifndef WIDGET_H
 3 #define WIDGET_H
 4 
 5 #include <QWidget>
 6 #include "mythread.h"
 7 
 8 
 9 QT_BEGIN_NAMESPACE
10 namespace Ui { class Widget; }
11 QT_END_NAMESPACE
12 
13 class Widget : public QWidget
14 {
15     Q_OBJECT
16 
17 public:
18     Widget(QWidget *parent = nullptr);
19     ~Widget();
20 
21 private slots:
22     void on_startBut_clicked();
23 
24     void on_stopBut_clicked();
25 
26 private:
27     Ui::Widget *ui;
28     MyThread thread;
29 };
30 #endif // WIDGET_H
 1 //widget.cpp
 2 
 3 #include "widget.h"
 4 #include "ui_widget.h"
 5 
 6 Widget::Widget(QWidget *parent)
 7     : QWidget(parent)
 8     , ui(new Ui::Widget)
 9 {
10     ui->setupUi(this);
11     ui->startBut->setEnabled(true);
12     ui->stopBut->setEnabled(false);
13 }
14 
15 Widget::~Widget()
16 {
17     delete ui;
18 }
19 
20 
21 void Widget::on_startBut_clicked()
22 {
23     thread.start();
24     ui->startBut->setEnabled(false);
25     ui->stopBut->setEnabled(true);
26 }
27 
28 void Widget::on_stopBut_clicked()
29 {
30     if( thread.isRunning() )
31     {
32         thread.stop();
33         ui->startBut->setEnabled(true);
34         ui->stopBut->setEnabled(false);
35     }
36 }

qt創(chuàng)建多線程的方法,qt,ui,開(kāi)發(fā)語(yǔ)言

qt創(chuàng)建多線程的方法,qt,ui,開(kāi)發(fā)語(yǔ)言

qt創(chuàng)建多線程的方法,qt,ui,開(kāi)發(fā)語(yǔ)言

二、使用moveToThread將一個(gè)繼承QObject的子類(lèi)移至線程

更加靈活,不需要繼承QThread,不需要重寫(xiě)run方法,適用于復(fù)雜業(yè)務(wù)的實(shí)現(xiàn)。

注意,該業(yè)務(wù)類(lèi)的不同槽函數(shù)均在同一個(gè)線程中執(zhí)行。

 1 //worker.h
 2 #ifndef WORKER_H
 3 #define WORKER_H
 4 
 5 #include <QObject>
 6 
 7 class Worker : public QObject
 8 {
 9     Q_OBJECT
10 
11 public:
12     Worker();
13 
14     ~Worker();
15 
16 public slots:
17     void doWork();
18 
19     void another();
20 
21 signals:
22     void stopWork();
23 
24 };
25 
26 #endif // WORKER_H
 1 //worker.cpp
 2 #include "worker.h"
 3 #include <QDebug>
 4 #include <QThread>
 5 
 6 Worker::Worker()
 7 {
 8 
 9 }
10 
11 
12 Worker::~Worker()
13 {
14 
15 }
16 
17 
18 void Worker::doWork()
19 {
20     qDebug() << "current thread id is " << QThread::currentThreadId();
21     emit stopWork();
22 }
23 
24 
25 void Worker::another()
26 {
27     qDebug() << "another current thread id is " << QThread::currentThreadId();
28     //emit stopWork();
29 }
 1 //dialog.h
 2 #ifndef DIALOG_H
 3 #define DIALOG_H
 4 
 5 #include <QDialog>
 6 #include <QThread>
 7 #include "worker.h"
 8 
 9 QT_BEGIN_NAMESPACE
10 namespace Ui { class Dialog; }
11 QT_END_NAMESPACE
12 
13 class Dialog : public QDialog
14 {
15     Q_OBJECT
16 
17 public:
18     Dialog(QWidget *parent = nullptr);
19     ~Dialog();
20 
21 signals:
22     void startWork();
23     void startAnother();
24 
25 public slots:
26     void endThread();
27 
28 private:
29     Ui::Dialog *ui;
30     QThread *m_pThread;
31     Worker *m_pWorker;
32 };
33 #endif // DIALOG_H
 1 //dialog.cpp
 2 #include "dialog.h"
 3 #include "ui_dialog.h"
 4 #include <QDebug>
 5 
 6 Dialog::Dialog(QWidget *parent)
 7     : QDialog(parent)
 8     , ui(new Ui::Dialog)
 9 {
10     ui->setupUi(this);
11 
12     m_pThread = new QThread();
13     m_pWorker = new Worker();
14 
15     connect(this, &Dialog::startWork, m_pWorker, &Worker::doWork);
16     connect(this, &Dialog::startAnother, m_pWorker, &Worker::another);
17     connect(m_pWorker, &Worker::stopWork, this, &Dialog::endThread);
18     m_pWorker->moveToThread(m_pThread);
19     m_pThread->start();
20     emit startWork();
21     emit startAnother();
22 }
23 
24 Dialog::~Dialog()
25 {
26     delete ui;
27     delete m_pThread;
28     delete m_pWorker;
29 }
30 
31 
32 void Dialog::endThread()
33 {
34     qDebug() << "endThread";
35     m_pThread->quit();
36     m_pThread->wait();
37 }

qt創(chuàng)建多線程的方法,qt,ui,開(kāi)發(fā)語(yǔ)言

不過(guò)我為什么要用界面類(lèi)呢?搞不懂!

三、使用QThreadPool,搭配QRunnable

QRunnable常用接口:

  bool QRunnable::autoDelete() const;

  void QRunnable::setAutoDelete(bool autoDelete);

  • QRunnable 常用函數(shù)不多,主要設(shè)置其傳到底給線程池后,是否需要自動(dòng)析構(gòu);
  • 若該值為false,則需要程序員手動(dòng)析構(gòu),要注意內(nèi)存泄漏;

QThreadPool常用接口:

  void QThreadPool::start(QRunnable * runnable, int priority = 0);

  bool QThreadPool::tryStart(QRunnable * runnable);

  • start() 預(yù)定一個(gè)線程用于執(zhí)行QRunnable接口,當(dāng)預(yù)定的線程數(shù)量超出線程池的最大線程數(shù)后,QRunnable接口將會(huì)進(jìn)入隊(duì)列,等有空閑線程后,再執(zhí)行;
  • priority指定優(yōu)先級(jí)
  • tryStart()start() 的不同之處在于,當(dāng)沒(méi)有空閑線程后,不進(jìn)入隊(duì)列,返回false

業(yè)務(wù)類(lèi)需要繼承QRunnable,并且重寫(xiě)run()方法。注意,QRunnbale不是QObject的子類(lèi),可以發(fā)射信號(hào),但用不了槽函數(shù)。

優(yōu)點(diǎn):無(wú)需手動(dòng)釋放資源,QThreadPool啟動(dòng)線程執(zhí)行完成后會(huì)自動(dòng)釋放。
缺點(diǎn):不能使用信號(hào)槽與外界通信。
適用場(chǎng)景:QRunnable適用于線程任務(wù)量比較大,需要頻繁創(chuàng)建線程。QRunnable能有效減少內(nèi)存開(kāi)銷(xiāo)

 1 //myrunnable.h
 2 #ifndef MYRUNNABLE_H
 3 #define MYRUNNABLE_H
 4 
 5 #include <QRunnable>
 6 #include <QString>
 7 
 8 
 9 class MyRunnable : public QRunnable
10 {
11 public:
12     MyRunnable(const QString szThreadName);
13     void run();
14 
15 private:
16     QString m_szThreadName;
17 };
18 
19 #endif // MYRUNNABLE_H
 1 //myrunnable.cpp
 2 #include "myrunnable.h"
 3 #include <QDebug>
 4 #include <QThread>
 5 
 6 MyRunnable::MyRunnable(const QString szThreadName) : m_szThreadName(szThreadName)
 7 {
 8 
 9 }
10 
11 
12 void MyRunnable::run()
13 {
14     qDebug() << "Start thread id : " << QThread::currentThreadId();
15     int iCount = 0;
16 
17     while (1)
18     {
19         if(iCount >= 10)
20         {
21             break;
22         }
23 
24         qDebug() << m_szThreadName << " count : " << iCount++;
25         QThread::msleep(500);
26     }
27 }
 1 //mian.cpp
 2 #include <QCoreApplication>
 3 #include "myrunnable.h"
 4 #include <QThreadPool>
 5 
 6 static QThreadPool* g_pThreadPool = NULL;
 7 
 8 int main(int argc, char *argv[])
 9 {
10     QCoreApplication a(argc, argv);
11 
12     MyRunnable* pRunnable1 = new MyRunnable("1# thread");
13     pRunnable1->setAutoDelete(true);
14 
15     MyRunnable* pRunnable2 = new MyRunnable("2# thread");
16     pRunnable2->setAutoDelete(true);
17 
18     g_pThreadPool = QThreadPool::globalInstance();
19 
20     g_pThreadPool->start(pRunnable1);
21     g_pThreadPool->start(pRunnable2);
22 
23     g_pThreadPool = NULL;
24 
25     return a.exec();
26 }

qt創(chuàng)建多線程的方法,qt,ui,開(kāi)發(fā)語(yǔ)言

四、使用QtConcurrent

Concurrent是并發(fā)的意思,QtConcurrent是一個(gè)命名空間,提供了一些高級(jí)的 API,使得在編寫(xiě)多線程的時(shí)候,無(wú)需使用低級(jí)線程原語(yǔ),如讀寫(xiě)鎖,等待條件或信號(hào)。使用QtConcurrent編寫(xiě)的程序會(huì)根據(jù)可用的處理器內(nèi)核數(shù)自動(dòng)調(diào)整使用的線程數(shù)。這意味著今后編寫(xiě)的應(yīng)用程序?qū)⒃谖磥?lái)部署在多核系統(tǒng)上時(shí)繼續(xù)擴(kuò)展。

QtConcurrent::run能夠方便快捷的將任務(wù)丟到子線程中去執(zhí)行,無(wú)需繼承任何類(lèi),也不需要重寫(xiě)函數(shù),使用非常簡(jiǎn)單。

QtConcurrent常用接口:

  QFuture<T> QtConcurrent::run(Function function, ...)

  QFuture<T> QtConcurrent::run(QThreadPool *pool, Function function, ...)

需要在pro文件中添加:

QT      += concurrent
 1 //main.cpp
 2 #include <QCoreApplication>
 3 #include <QThread>
 4 #include <QThreadPool>
 5 #include <QtConcurrent/QtConcurrent>
 6 #include <QDebug>
 7 #include <QFuture>
 8 
 9 static QThreadPool* g_pThreadPool = QThreadPool::globalInstance();
10 
11 class HELLO
12 {
13 public:
14     QString hello(QString szName)
15     {
16         qDebug() << "Hello " << szName << " from " << QThread::currentThreadId();
17         return szName;
18     }
19 
20     void run()
21     {
22         QFuture<QString> f3 = QtConcurrent::run(this, &HELLO::hello, QString("Lily"));
23         QFuture<QString> f4 = QtConcurrent::run(g_pThreadPool, this, &HELLO::hello, QString("Sam"));
24 
25         f3.waitForFinished();
26         f4.waitForFinished();
27 
28         qDebug() << "f3 : " << f3.result();
29         qDebug() << "f4 : " << f4.result();
30     }
31 };
32 
33 QString hello(QString szName)
34 {
35     qDebug() << "Hello " << szName << " from " << QThread::currentThreadId();
36     return szName;
37 }
38 
39 int main(int argc, char *argv[])
40 {
41     QCoreApplication a(argc, argv);
42 
43     QFuture<QString> f1 = QtConcurrent::run(hello, QString("Alice"));
44     QFuture<QString> f2 = QtConcurrent::run(g_pThreadPool, hello, QString("Bob"));
45 
46     f1.waitForFinished();
47     f2.waitForFinished();
48 
49     qDebug() << "f1 : " << f1.result();
50     qDebug() << "f2 : " << f2.result();
51 
52     HELLO h;
53     h.run();
54 
55     g_pThreadPool = NULL;
56 
57     return a.exec();
58 }

qt創(chuàng)建多線程的方法,qt,ui,開(kāi)發(fā)語(yǔ)言文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-558238.html

到了這里,關(guān)于Qt 多線程的幾種實(shí)現(xiàn)方式的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶(hù)投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Qt 播放音頻文件的幾種方式

    Qt 播放音頻文件的幾種方式

    : Qt 、 QSound 、 QSoundEffect 、 QMediaPlayer 、 multimedia 這篇文章至少拖了有一兩個(gè)月了,這不陽(yáng)了,在家實(shí)在是難受的要死,無(wú)心處理工作的事情,那就寫(xiě)寫(xiě)博客吧,因?yàn)轫?xiàng)目中需要用到播放音頻的功能,CV了部分代碼,這里就簡(jiǎn)單的扯扯我對(duì) QSound 、 QSoundEffect 和 QMediaP

    2024年02月11日
    瀏覽(18)
  • qt初入門(mén)1:qt讀文件的幾種方式簡(jiǎn)單整理

    工作變動(dòng)開(kāi)始接觸qt,涉及到qt讀文件相關(guān)業(yè)務(wù),簡(jiǎn)單整理一下qt讀文件幾種方式,后面發(fā)現(xiàn)有其他的再新增 測(cè)試demo的方式歸納匯總幾種讀qt文件的方法 : 1:獲取文件源按鈕,并打印獲取到的相關(guān)文件名 2:使用qfile直接讀文件,顯示耗時(shí)時(shí)間 3:使用qdatastream讀文件,顯示耗

    2024年02月12日
    瀏覽(19)
  • 【昕寶爸爸小模塊】淺談之創(chuàng)建線程的幾種方式

    【昕寶爸爸小模塊】淺談之創(chuàng)建線程的幾種方式

    ??博客首頁(yè)???????https://blog.csdn.net/Java_Yangxiaoyuan ???????歡迎優(yōu)秀的你??點(diǎn)贊、???收藏、加??關(guān)注哦。 ???????本文章CSDN首發(fā),歡迎轉(zhuǎn)載,要注明出處哦! ???????先感謝優(yōu)秀的你能認(rèn)真的看完本文,有問(wèn)題歡迎評(píng)論區(qū)交流,都會(huì)認(rèn)真回復(fù)! 在Java中,共有

    2024年01月18日
    瀏覽(18)
  • Qt中正確的設(shè)置窗體的背景圖片的幾種方式

    Qt中正確的設(shè)置窗體的背景圖片的幾種方式

    原文鏈接:https://blog.csdn.net/yanche521/article/details/51017601 Qt中正確的設(shè)置窗體的背景圖片的方法大致有兩種,下面將逐個(gè)講解: 使用stylesheet設(shè)置窗體的背景圖片的時(shí)候,可以直接按照下圖的操作去進(jìn)行即可,如下圖所示: 但是,需要注意的是: 1.在QWidget中這種方法是不行的,

    2024年02月05日
    瀏覽(25)
  • 線程間實(shí)現(xiàn)通信的幾種方式

    線程間實(shí)現(xiàn)通信的幾種方式

    線程間通信的模型有兩種:共享內(nèi)存和消息傳遞,下面介紹的都是圍繞這兩個(gè)來(lái)實(shí)現(xiàn) 有兩個(gè)線程A和B,B線程向一個(gè)集合里面依次添加元素“abc”字符串,一共添加10次,當(dāng)添加到第五次的時(shí)候,希望線程A能夠收到線程B的通知,然后B線程執(zhí)行相關(guān)的業(yè)務(wù)操作 Object類(lèi)提供了線程

    2024年02月15日
    瀏覽(24)
  • 【Qt】qDebug() 輸出16進(jìn)制數(shù)的幾種方法

    Qt qDebug() 輸出16進(jìn)制數(shù)字的幾種方法整理:

    2024年04月28日
    瀏覽(26)
  • QT中信號(hào)與槽機(jī)制的介紹,以及信號(hào)與槽連接的幾種方式

    功能:實(shí)現(xiàn)多個(gè)組件之間的相互通信,是QT引以為傲的核心機(jī)制 信號(hào):就是信號(hào)函數(shù),定義在類(lèi)體的signals權(quán)限下,是一個(gè)不完整的函數(shù),只有聲明沒(méi)有定義; 槽:就是槽函數(shù),定義在類(lèi)體的slots權(quán)限下,是一個(gè)完整的函數(shù),既有聲明也有定義,也可以當(dāng)做普通函數(shù)被使用 無(wú)

    2024年02月10日
    瀏覽(21)
  • java 實(shí)現(xiàn)開(kāi)啟異步線程的幾種方式

    在Java中,有多種方式可以實(shí)現(xiàn)異步線程以避免在主線程中執(zhí)行耗時(shí)操作導(dǎo)致界面卡頓的問(wèn)題。以下是幾種常用的方式: 使用 Thread 類(lèi):可以使用 Thread 類(lèi)來(lái)創(chuàng)建一個(gè)新的線程,并在其 run() 方法中執(zhí)行耗時(shí)操作。例如: 使用 Runnable 接口:可以通過(guò)實(shí)現(xiàn) Runnable 接口并在其中實(shí)現(xiàn)

    2024年02月14日
    瀏覽(24)
  • C#針對(duì)VS線程間操作提示:程間操作無(wú)效: 從不是創(chuàng)建控件“”的線程訪問(wèn)它的幾種解決方法

    C#針對(duì)VS線程間操作提示:程間操作無(wú)效: 從不是創(chuàng)建控件“”的線程訪問(wèn)它的幾種解決方法

    轉(zhuǎn)載請(qǐng)標(biāo)明出處:Python Excellent的博客 此為最基礎(chǔ)方法 (入門(mén)級(jí)) 運(yùn)行效果如圖所示 * 先在按鈕事件中創(chuàng)建一個(gè)Test1()線程 * 在測(cè)試1中有兩種方法可以訪問(wèn)窗體線程(首推薦) public SynchronizationContext UiContext //第一步全局聲明 UiContext = SynchronizationContext.Current; //第二部在public For

    2024年02月08日
    瀏覽(23)
  • QT創(chuàng)建線程的方法:一步步教你創(chuàng)建和啟動(dòng)線程

    QT創(chuàng)建線程的方法:一步步教你創(chuàng)建和啟動(dòng)線程

    目錄 線程概念及官方文檔 ?一、線程的創(chuàng)建:繼承方式 二、線程的創(chuàng)建:QObject 對(duì)象(moveToThread) 2.1 創(chuàng)建任務(wù)類(lèi) 2.2 添加線程啟動(dòng)(定時(shí)器啟動(dòng)) 2.3?添加線程啟動(dòng)(start信號(hào)啟動(dòng)) 三、線程類(lèi)的基本接口和使用 3.1啟動(dòng) 和終止線程 3.2 線程延遲 3.3 線程同步及通信方式 3.4

    2024年02月13日
    瀏覽(20)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包