最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一文帶你了解Qt多線程的實(shí)現(xiàn)方式

 更新時(shí)間:2025年01月03日 16:01:46   作者:Liknana  
這篇文章主要為大家詳細(xì)介紹了Qt多線程的實(shí)現(xiàn)方式的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

QThread的run方法

一個(gè)QThread對(duì)象管理一個(gè)線程,一般從QThread繼承一個(gè)自定義的類,并實(shí)現(xiàn)run方法,在run函數(shù)中實(shí)現(xiàn)線程需要完成的任務(wù)。QThread自身定義了started() 和finish()兩個(gè)信號(hào),started() 信號(hào)是在開(kāi)始執(zhí)行之前發(fā)射,finished()信號(hào)是在線程就要結(jié)束時(shí)發(fā)射。

  class WorkerThread : public QThread
  {
      Q_OBJECT
      void run() override {
          // TODO
          emit sigMsg(result);
      }
  signals:
      void sigMsg(const QString &s);
  };

  void main()
  {
      WorkerThread *workerThread = new WorkerThread(this);
      workerThread->start();
  }

特點(diǎn)

1、優(yōu)點(diǎn):可以通過(guò)信號(hào)槽與外界進(jìn)行通信。

2、缺點(diǎn):每次新建一個(gè)線程都需要繼承QThread,實(shí)現(xiàn)一個(gè)新類,使用不太方便。

要自己進(jìn)行資源管理,線程釋放和刪除。并且頻繁的創(chuàng)建和釋放會(huì)帶來(lái)比較大的內(nèi)存開(kāi)銷。

3、適用場(chǎng)景:QThread適用于那些常駐內(nèi)存的任務(wù)。

QObject的moveToThread

創(chuàng)建一個(gè)繼承QObject的類MyThread,把要執(zhí)行的計(jì)算放到一個(gè)函數(shù)中doWork,然后new一個(gè)Qthread,并把創(chuàng)建的myThread類movetothread到創(chuàng)建好的子線程中,然后start子線程,這樣就實(shí)現(xiàn)了一個(gè)子線程。這里一定要通過(guò)信號(hào)去調(diào)用doWork函數(shù)。

class MyThread:public QObject
{
    Q_OBJECT
public slots:
    void doWork(){
        int i=0;
        while(i<4){
            // ToDo
            qDebug()<<QThread::currentThread()<<" "<<i++;
        }
    }
?
?
};
?
class MyTest :public QObject
{
    Q_OBJECT
    QThread workerThread;
public:
    MyTest(){
        MyThread* myThread = new MyThread();   // 這個(gè)任務(wù)函數(shù)不能有父對(duì)象,有父對(duì)象時(shí)不可以moveToThread
        myThread->moveToThread(&workerThread);
        workerThread.start();
        connect(this,&MyTest::active,myThread,&MyThread::doWork);  // 一定要通過(guò)槽函數(shù)去調(diào)用對(duì)應(yīng)的函數(shù),否則還是在主線程
    }
    ~MyTest(){
        workerThread.quit();
    }
signals:
    void active();
};
?
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    qDebug()<<QThread::currentThread();
    ui->setupUi(this);
    MyTest* t = new MyTest();
    t->active();
    QThread::sleep(3000);
    t->deleteLater();
}

特點(diǎn)

一定要通過(guò)槽函數(shù)的形式去調(diào)用函數(shù),要注意!你創(chuàng)建的QThread對(duì)象實(shí)例,仍然存活在主線程上,而非子線程。所以如果你直接調(diào)用其中的函數(shù),那么還是在主線程上運(yùn)行的。該方法并不是線程安全的。

QRunnalble的run

繼承Qrunnable,并重寫run虛函數(shù),使用QThreadPool啟動(dòng)線程

class Runnable:public QRunnable
{
public:
       Runnable();
       ~Runnable();
       void run();
};

Runnable::Runnable():QRunnable()
{

}

Runnable::~Runnable()
{
       cout<<"~Runnable()"<<endl;
}

void Runnable::run()
{
       cout<<"Runnable::run()thread :"<<QThread::currentThreadId()<<endl;
       cout<<"dosomething ...."<<endl;
}
int main(int argc, char *argv[])
{
       QCoreApplication a(argc, argv);
       cout<<"mainthread :"<<QThread::currentThreadId()<<endl;
       Runnable runObj;
       QThreadPool::globalInstance()->start(&runObj);
       returna.exec();
}

特點(diǎn)

1,無(wú)需手動(dòng)釋放資源,QThreadPool啟動(dòng)線程執(zhí)行完成后會(huì)自動(dòng)釋放。

2,不能使用信號(hào)槽與外界通信。

3,QRunnable適用于線程任務(wù)量比較大,需要頻繁創(chuàng)建線程。QRunnable能有效減少內(nèi)存開(kāi)銷。

QtConcurrent的run

使用QtConcurrent編寫的程序會(huì)根據(jù)可用的處理器內(nèi)核數(shù)自動(dòng)調(diào)整使用的線程數(shù)。QtConcurrent::run能夠方便快捷的將任務(wù)丟到子線程中去執(zhí)行,無(wú)需繼承任何類,也不需要重寫函數(shù),使用非常簡(jiǎn)單。通過(guò)QtConcurrent::run()返回的QFuture不支持取消、暫停,返回的QFuture只能用于查詢函數(shù)的運(yùn)行/完成狀態(tài)和返回值。

函數(shù)原型:

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

使用方式

    QtConcurrent::run([=]() {
        // TODO
    });

線程同步

基于QMutex互斥同步

QMutex的目的是保護(hù)一個(gè)對(duì)象、數(shù)據(jù)結(jié)構(gòu)或者代碼段,所以同一時(shí)間只有一個(gè)線程可以訪問(wèn)它。如果使用Mutex鎖那么多個(gè)線程在訪問(wèn)一段代碼的時(shí)候是存在阻塞的,一個(gè)執(zhí)行完畢下一個(gè)線程才會(huì)繼續(xù)執(zhí)行

lock():試圖鎖定互斥量。如果另一個(gè)線程已經(jīng)鎖定這個(gè)互斥量,那么這次調(diào)用將阻塞直到那個(gè)線程把它解鎖。

unlock():進(jìn)行解鎖

tryLock():試圖鎖定互斥量。如果鎖被得到,這個(gè)函數(shù)返回真。如果另一個(gè)進(jìn)程已經(jīng)鎖定了這個(gè)互斥量,這個(gè)函數(shù)返回假,而不是一直等到這個(gè)鎖可用為止

QMutex mutex;
 void DebugInfo()
 {
    mutex.lock();
    qDebug("ABC");
    qDebug("DEF");
    mutex.unlock();
 }

基于QReadWriteLock的線程同步

一種讀寫鎖,用于保護(hù)可以進(jìn)行讀寫訪問(wèn)的資源。這種索允許多個(gè)線程同時(shí)進(jìn)行只讀訪問(wèn),但是一旦一個(gè)線程想要寫入資源,則必須阻止所有其他線程,直到寫入完成。

 QReadWriteLock lock;

 void ReaderThread::run()
 {
     ...
     lock.lockForRead();
     read_file();
     lock.unlock();
     ...
 }

 void WriterThread::run()
 {
     ...
     lock.lockForWrite();
     write_file();
     lock.unlock();
     ...
 }

void lockForRead():鎖定讀取鎖。如果另一個(gè)線程已鎖定以進(jìn)行寫入,則此函數(shù)將阻塞當(dāng)前線程。如果線程已經(jīng)鎖定寫入,則無(wú)法鎖定讀取。void lockForWrite():鎖定寫入鎖。如果另一個(gè)線程(包括當(dāng)前線程)已鎖定讀取或?qū)懭?,則此函數(shù)將阻塞當(dāng)前線程。如果線程已經(jīng)為讀取而鎖定,則不會(huì)為寫入而鎖定。

基于QWaitCondition的線程同步

QWaitCondition 允許線程在某些情況發(fā)生時(shí)喚醒另外的線程。一個(gè)或多個(gè)線程可以阻塞等待一QWaitCondition ,用wakeOne()或wakeAll()設(shè)置一個(gè)條件。wakeOne()隨機(jī)喚醒一個(gè),wakeAll()喚醒所有

const int DataSize = 100000;
const int BufferSize = 8192;
char buffer[BufferSize];
QWaitCondition bufferNotEmpty;
QWaitCondition bufferNotFull;
QMutex mutex;
int numUsedBytes = 0;
class Producer : public QThread
{
public:
     void run();
};
void Producer::run()
{
     qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
     for (int i = 0; i < DataSize; ++i) {
         mutex.lock();
         if (numUsedBytes == BufferSize)
             bufferNotFull.wait(&mutex);
         mutex.unlock();
         buffer[i % BufferSize] = "ACGT"[(int)qrand() % 4];
         mutex.lock();
         ++numUsedBytes;
         bufferNotEmpty.wakeAll();
         mutex.unlock();
     }
}
class Consumer : public QThread
{
public:
     void run();
};
void Consumer::run()
{
     for (int i = 0; i < DataSize; ++i) {
         mutex.lock();
         if (numUsedBytes == 0)
             bufferNotEmpty.wait(&mutex);
         mutex.unlock();
         fprintf(stderr, "%c", buffer[i % BufferSize]);
         mutex.lock();
         --numUsedBytes;
         bufferNotFull.wakeAll();
         mutex.unlock();
     }
     fprintf(stderr, "\n");
}
int main(int argc, char *argv[])
{
     QCoreApplication app(argc, argv);
     Producer producer;
     Consumer consumer;
     producer.start();
     consumer.start();
     producer.wait();
     consumer.wait();
     return 0;
}

到此這篇關(guān)于一文帶你了解Qt多線程的實(shí)現(xiàn)方式的文章就介紹到這了,更多相關(guān)Qt多線程內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++冒泡排序算法實(shí)例

    C++冒泡排序算法實(shí)例

    這篇文章主要介紹了C++冒泡排序算法實(shí)例,本文先是介紹了什么是冒泡排序,然后給出了實(shí)現(xiàn)代碼,需要的朋友可以參考下
    2014-10-10
  • 純C語(yǔ)言:遞歸最大數(shù)源碼分享

    純C語(yǔ)言:遞歸最大數(shù)源碼分享

    這篇文章主要介紹了純C語(yǔ)言:遞歸最大數(shù)源碼,需要的朋友可以參考一下
    2014-01-01
  • C++中rapidjson將map轉(zhuǎn)為json的方法

    C++中rapidjson將map轉(zhuǎn)為json的方法

    今天小編就為大家分享一篇關(guān)于C++中rapidjson將map轉(zhuǎn)為json的方法,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-04-04
  • VC6實(shí)現(xiàn)激活后臺(tái)窗口最佳方法

    VC6實(shí)現(xiàn)激活后臺(tái)窗口最佳方法

    這篇文章主要介紹了VC6實(shí)現(xiàn)激活后臺(tái)窗口最佳方法,實(shí)例分析了VC操作后臺(tái)窗口的技巧,需要的朋友可以參考下
    2015-06-06
  • QT5多窗口跳轉(zhuǎn)實(shí)現(xiàn)步驟詳解

    QT5多窗口跳轉(zhuǎn)實(shí)現(xiàn)步驟詳解

    這篇文章主要介紹了使用Qt5實(shí)現(xiàn)多窗口界面跳轉(zhuǎn)的過(guò)程,包括創(chuàng)建多個(gè)UI界面、設(shè)計(jì)按鈕連接槽函數(shù)以及實(shí)現(xiàn)界面之間的導(dǎo)航,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-12-12
  • C語(yǔ)言代碼實(shí)現(xiàn)猜數(shù)字

    C語(yǔ)言代碼實(shí)現(xiàn)猜數(shù)字

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言代碼實(shí)現(xiàn)猜數(shù)字,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-11-11
  • C++如何向Lambda傳遞參數(shù)與捕獲

    C++如何向Lambda傳遞參數(shù)與捕獲

    文章介紹了C++中向Lambda表達(dá)式傳遞參數(shù)和使用捕獲列表的基本規(guī)則和示例,參數(shù)傳遞要求嚴(yán)格匹配類型和數(shù)量,而捕獲列表允許Lambda訪問(wèn)外部變量,并可以按值或引用捕獲,文章還討論了捕獲的陷阱和解決方案,以及參數(shù)傳遞與捕獲列表的區(qū)別和應(yīng)用場(chǎng)景,感興趣的朋友一起看看吧
    2025-03-03
  • C語(yǔ)言 數(shù)據(jù)結(jié)構(gòu)與算法之字符串詳解

    C語(yǔ)言 數(shù)據(jù)結(jié)構(gòu)與算法之字符串詳解

    這篇文章將帶大家深入了解C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)與算法中的字符串,文中主要是介紹了字符串的定義、字符串的比較以及一些串的抽象數(shù)據(jù)類型,感興趣的可以學(xué)習(xí)一下
    2022-01-01
  • C語(yǔ)言安全的進(jìn)行字符串拷貝的幾種方法

    C語(yǔ)言安全的進(jìn)行字符串拷貝的幾種方法

    在C語(yǔ)言編程中,字符串是通過(guò)定義char數(shù)組來(lái)保存,并通過(guò)指針以及字符串拷貝函數(shù)來(lái)實(shí)現(xiàn)字符串的拷貝,在字符串長(zhǎng)度不太明確的情況下,可能處出現(xiàn)拷貝越界的情況,給程序引入了不安全的因素,本篇就來(lái)討論下,在C語(yǔ)言中,如何安全的使用strcpy這類函數(shù)進(jìn)行字符串的拷貝
    2026-06-06
  • C語(yǔ)言 fgetc的用法詳解以注意事項(xiàng)場(chǎng)景分析

    C語(yǔ)言 fgetc的用法詳解以注意事項(xiàng)場(chǎng)景分析

    fgetc是C語(yǔ)言標(biāo)準(zhǔn)庫(kù)中用于從文件流讀取單個(gè)字符的函數(shù),本文給大家介紹C語(yǔ)言fgetc的用法詳解以注意事項(xiàng)場(chǎng)景分析,感興趣的朋友一起看看吧
    2025-06-06

最新評(píng)論

梨树县| 丰原市| 东丽区| 博湖县| 左云县| 古蔺县| 辰溪县| 沙雅县| 永嘉县| 宜都市| 施甸县| 洛浦县| 营山县| 阿合奇县| 宝山区| 岗巴县| 辽源市| 卓资县| 屏东市| 溧阳市| 鄯善县| 岳阳县| 蕉岭县| 南乐县| 五指山市| 江阴市| 布尔津县| 麻城市| 瑞安市| 宣武区| 民丰县| 尤溪县| 陇川县| 莎车县| 抚顺市| 平昌县| 金山区| 荆州市| 墨脱县| 江城| 太湖县|