日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

Qt多线程-QThreadPool线程池与QRunnable

發布時間:2025/3/15 c/c++ 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Qt多线程-QThreadPool线程池与QRunnable 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
版權聲明:若無來源注明,Techie亮博客文章均為原創。 轉載請以鏈接形式標明本文標題和地址:
本文標題:Qt多線程-QThreadPool線程池與QRunnable?????本文地址:http://techieliang.com/2017/12/605/ 文章目錄
  • 1. 介紹
  • 2. QThreadPool
  • ?2.1. 基本操作函數
  • ?2.2. start tryStart tryTake
  • ?2.3. 全局線程池
  • ?2.4. 局部線程池
  • 3. QRunnable
  • 4. 范例
  • ?4.1. 簡單使用范例
  • ?4.2. 全局線程池和局部線程池對比

1. 介紹

線程的創建及銷毀需要與系統交互,會產生很大的開銷。若需要頻繁的創建線程建議使用線程池,有線程池維護一定數量的線程,當需要進行多線程運算時將運算函數傳遞給線程池即可。線程池會根據可用線程進行任務安排。

2. QThreadPool

相關幫助文檔:QThreadPool

此類為Qt提供的線程池函數,使用此類只需要配置線程池的最大線程數量、線程長時間不使用的過期時間等參數,不需要進行QThread相關的操作。

此類有兩種使用方式:全局線程池和局部線程池。下面首先介紹兩種類型后續介紹類提供的方法

2.1. 基本操作函數

  • int?activeThreadCount()?const?//當前的活動線程數量
  • void?clear()//清除所有當前排隊但未開始運行的任務
  • int?expiryTimeout()?const//線程長時間未使用將會自動退出節約資源,此函數返回等待時間
  • int?maxThreadCount()?const//線程池可維護的最大線程數量
  • void?releaseThread()//釋放被保留的線程
  • void?reserveThread()//保留線程,此線程將不會占用最大線程數量,從而可能會引起當前活動線程數量大于最大線程數量的情況
  • void?setExpiryTimeout(int?expiryTimeout)//設置線程回收的等待時間
  • void?setMaxThreadCount(int?maxThreadCount)//設置最大線程數量
  • void?setStackSize(uint stackSize)//此屬性包含線程池工作線程的堆棧大小。
  • uint?stackSize()?const//堆大小
  • void?start(QRunnable *runnable,?int?priority =?0)//加入一個運算到隊列,注意start不一定立刻啟動,只是插入到隊列,排到了才會開始運行。需要傳入QRunnable ,后續介紹
  • bool?tryStart(QRunnable *runnable)//嘗試啟動一個
  • bool?tryTake(QRunnable *runnable)//刪除隊列中的一個QRunnable,若當前QRunnable 未啟動則返回成功,正在運行則返回失敗
  • bool?waitForDone(int?<i>msecs</i>?=?-1)//等待所有線程運行結束并退出,參數為等待時間-1表示一直等待到最后一個線程退出
  • QThread::idealThreadCount函數,會根據當前設備的硬件情況給出一個線程數量,而maxThreadCount的默認值就是此值。

    setStackSize

    只有在線程池創建新線程時才使用該屬性的值。更改它對已經創建或運行的線程沒有影響。默認值是0,這使得qthread使用操作系統默認的堆棧大小。

    The value of the property is only used when the thread pool creates new threads. Changing it has no effect for already created or running threads.

    The default value is 0, which makes?QThread?use the operating system default stack size.

    maxThreadCount? reserveThread? activeThreadCount

    由于reserveThread 后的線程不計入線程數量,因此可能出現activeThreadCount>maxThreadCount? 情況

    Note:?It is possible for this function to return a value that is greater than?maxThreadCount(). See?reserveThread() for more details.

    2.2. start tryStart tryTake

    對于start,傳入的是QRunnable對象指針,傳入后線程池會調用QRunnable的autoDelete() 函數,若返回true,則當此運算完成后自動釋放內容,不需要后續主動判斷是否運算完成并釋放空間。

    對于tryTake,若返回成功,不會自動釋放內容,而是需要調用方主動釋放,無論autodelete返回值是什么。返回false自然也不會自動delete

    Attempts to remove the specified?runnable?from the queue if it is not yet started. If the runnable had not been started, returns?true, and ownership of?runnable?is transferred to the caller (even when?runnable->autoDelete() == true). Otherwise returns?false.

    Note:?If?runnable->autoDelete() == true, this function may remove the wrong runnable. This is known as the?ABA problem: the original?runnable?may already have executed and has since been deleted. The memory is re-used for another runnable, which then gets removed instead of the intended one. For this reason, we recommend calling this function only for runnables that are not auto-deleting.

    對于tryStart,若返回成功,等同于start,若false,則不會自動delete

    注意,對于autoDelete必須在調用state/trytake之前進行修改,不要再調用以后修改,否則結果不可預測

    Note that changing the auto-deletion on?runnable?after calling this function results in undefined behavior.

    QRunnable的autoDelete默認返回true,若需要更改需要調用setAutoDelete進行更改

    2.3. 全局線程池

    QThreadPool提供了一個靜態函數,globalInstance(),使用此方法可獲取一個當前進程的全局線程池,可在多個類中共同使用一個線程池。

    2.4. 局部線程池

    和常規類的使用相同,可以通過? QThreadPool pool;的方式建立一個局部線程池,并由當前類維護,可保證此線程池僅供當前類應用

    3. QRunnable

    線程池每一個需要運行的任務均需要作為QRunnable的子類,并重寫其run函數,幫助文檔:http://doc.qt.io/qt-5/qrunnable.html

    QRunnable只有run、autodelete、setautodelete這三個關鍵函數。

    run內重寫需要運算的內容。

    autodelete用來標識是否在運行結束后自動由線程池釋放空間,具體說明見上述“QThreadPool-基本操作函數-start tryStart tryTake”

    4. 范例

    4.1. 簡單使用范例

  • #include <QCoreApplication>
  • #include <QThreadPool>
  • #include <QThread>
  • #include <QRunnable>
  • #include <QDebug>
  • class?MyRun :?public?QRunnable?{
  • public:
  • void?run()?{
  • int?i=3;
  • while(i)?{
  • i--;
  • qDebug()<<"thread start:"<<QThread::currentThreadId();
  • QThread::msleep(500);
  • }
  • }
  • };
  • int?main(int?argc,?char?*argv[])?{
  • QCoreApplication?a(argc, argv);
  • qDebug()<<"Main:"<<QThread::currentThreadId();
  • QThreadPool m;
  • MyRun *run=new?MyRun;
  • if(!run->autoDelete())?{
  • qDebug()<<"QRunnable's autoDelete default value is not true";
  • run->setAutoDelete(true);
  • }
  • qDebug()<<m.maxThreadCount()<<m.expiryTimeout();
  • qDebug()<<m.activeThreadCount();
  • m.start(run);
  • qDebug()<<m.activeThreadCount();
  • m.waitForDone();
  • qDebug()<<m.activeThreadCount();
  • return?0;
  • }
  • 結果:

  • Main:?0xffc
  • 4?30000
  • 0
  • 1
  • thread start:?0x7e4
  • thread start:?0x7e4
  • thread start:?0x7e4
  • 0
  • 4.2. 全局線程池和局部線程池對比

  • #include <QCoreApplication>
  • #include <QThreadPool>
  • #include <QThread>
  • #include <QRunnable>
  • #include <QDebug>
  • class?MyRun :?public?QRunnable?{
  • public:
  • void?run()?{
  • int?i=3;
  • while(i)?{
  • i--;
  • qDebug()<<"thread start:"<<QThread::currentThreadId();
  • QThread::msleep(500);
  • }
  • }
  • };
  • int?main(int?argc,?char?*argv[])?{
  • QCoreApplication?a(argc, argv);
  • qDebug()<<"Main:"<<QThread::currentThreadId();
  • QThreadPool pool;
  • QThreadPool *global_pool = QThreadPool::globalInstance();
  • MyRun *run=new?MyRun;
  • if(!run->autoDelete())?{
  • qDebug()<<"QRunnable's autoDelete default value is not true";
  • run->setAutoDelete(true);
  • }
  • pool.setMaxThreadCount(2);//修改了局部線程數量
  • qDebug()<<"pool:"<<pool.maxThreadCount()<<pool.expiryTimeout()<<"\r\nglobal"<<global_pool->maxThreadCount();
  • qDebug()<<pool.activeThreadCount()<<global_pool->activeThreadCount();
  • pool.start(run);
  • global_pool->start(new?MyRun);
  • qDebug()<<pool.activeThreadCount()<<global_pool->activeThreadCount();
  • pool.waitForDone();
  • global_pool->waitForDone();
  • qDebug()<<pool.activeThreadCount()<<global_pool->activeThreadCount();
  • return?0;
  • }
  • 結果

  • Main:?0x30c4
  • pool:?2?30000
  • global?4
  • 0?0
  • 1?1
  • thread start:?0x22d0
  • thread start:?0xfe0
  • thread start:?0x22d0
  • thread start:?0xfe0
  • thread start:?0x22d0
  • thread start:?0xfe0
  • 0?0
  • 當建立局部線程池,修改其參數后僅供局部使用,不會影響全局線程池的。

    轉載請以鏈接形式標明本文標題和地址:Techie亮博客???Qt多線程-QThreadPool線程池與QRunnable

    總結

    以上是生活随笔為你收集整理的Qt多线程-QThreadPool线程池与QRunnable的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。