QT 執行緒池

2021-09-19 07:30:46 字數 1293 閱讀 2827

在程式邏輯中經常會碰到需要處理大批量任務的情況,比如密集的網路請求,或者日誌分析等等。一般會建立乙個佇列,用乙個或者多個執行緒去消費這個佇列,一般也要處理佇列的加鎖和解鎖的問題,除非在設計時就能夠做到專列專用,否則鎖是不可避免的。而且在入隊和出隊的操作上肯定還是要加鎖,因為他們是在不同執行緒對同乙個資源進行操作。

執行緒池就是為這個而設計的,比如

windows自帶的執行緒池:   createthreadpoolwork  submitthreadpoolwork

boost的執行緒池: io_service std::thread, 由io_service來排程執行緒

qt: qthreadpool

這裡說qthreadpool, 最簡單的建立執行緒池的方法,就是建立乙個qthreadpool物件,然後呼叫start將繼承自qrunnable的任務物件傳入,這樣任務物件就被放入了執行緒池的佇列中。實現任務方法,需要繼承qrunnable並重寫run方法,執行緒池會呼叫這個方法來執行。

我們也可以呼叫qthreadpool::setmaxthreadcount來設定執行緒池的最大執行緒數,預設是同cpu核心數相同。

這裡要注意繼承自qrunnable生命週期如果沒有被管理起來,想要在執行完成後自動釋放,那就需要qrunnable::setautodelete(true),在執行完成後會自動釋放掉任務物件。

對於普通的任務消費,這幾個介面完全夠用了,qt還有乙個更簡易的用於執行任務的方法:

qtconcurrent::run這個方法其實也是將任務放入了乙個執行緒池中去處理,觀察一下他的介面:

qfutureqtconcurrent::run(function function, ...)

qfutureqtconcurrent::run(qthreadpool *pool, function function, ...)

第乙個介面只需要乙個function,文件上說這個介面等價於:

qtconcurrent::run(qthreadpool::globalinstance(), function, ...);
所以這個方法預設將任務放入了全域性執行緒池,那麼這個任務的執行的時機就會受到其他放入全域性執行緒池任務的多少和時間決定了,所以如果是緊急的任務,最好使用第二個介面,自己建立乙個專用線程池,將任務交給這個專用線程池去處理。

總的來講,執行緒池的思路大多相同,都是管理乙個公共佇列,然後開啟多個執行緒去消費,不同之處可能在於執行緒排程的演算法不同。有的執行緒池會檢測線程池中的任務量來決定是否要增加新執行緒,根據空閒時間來決定是否減少執行緒。有的執行緒池對任務增加了優先順序,可以讓優先順序高的任務先得以執行。

Qt的執行緒池QThreadPool

執行緒可以幫助我們處理耗時的操作以防止介面卡死,也可以提高程式的併發性。但執行緒也不是建立越多越好,因為建立 銷毀執行緒以及切換執行緒都是需要消耗資源的。執行緒池技術的出現就是為了解決這個問題。執行緒池維護一定數量的執行緒,並充分使用它們。qt封裝的執行緒池類是qthreadpool,它的使用需要q...

Qt執行緒池QThreadPool原始碼學習筆記

qlistallthreads 所有執行緒 qqueuewaitingthreads 等待佇列,當乙個執行緒中完成它的工作後,如果發現現有正在工作的執行緒數沒有超過設定上限數量,放到這裡,執行緒等待一定的時間,如果超時了,將這個執行緒放到expiredthreads qqueueexpiredthr...

qt執行緒,執行緒池用到的一點問題

總結一下最近使用qt多執行緒和執行緒池遇到的一些問題。1.qthreadpool 執行緒池的作用是什麼呢?把多個執行緒丟個乙個執行緒池中,讓他對目前的執行緒進行管理。比如最大執行的執行緒數,以及最大執行緒數外的執行緒就處於等待狀態等。要放到執行緒池中的執行緒必須繼承自qrunable類,這個類有個缺...