線程池大小設置,CPU的核心數、線程數的關系和區別,同步與堵塞完全是兩碼事


線程池大小設置,CPU的核心數、線程數的關系和區別,同步與堵塞完全是兩碼事

線程池應該設置多少線程合適,怎么樣估算出來。最近接觸到一些相關資料,現作如下總結。

最開始接觸線程池的時候,沒有想到就僅僅是設置一個線程池的大小居然還有這么多的學問,汗顏啊。

首先,需要考慮到線程池所進行的工作的性質:

  • IO密集型
  • CPU密集型

簡單的分析來看,如果是CPU密集型的任務,我們應該設置數目較小的線程數,比如CPU數目加1。如果是IO密集型的任務,則應該設置可能多的線程數,由於IO操作不占用CPU,所以,不能讓CPU閑下來。當然,如果線程數目太多,那么線程切換所帶來的開銷又會對系統的響應時間帶來影響。

《linux多線程服務器端編程》中有一個思路,CPU計算和IO的阻抗匹配原則。

如果線程池中的線程在執行任務時,密集計算所占的時間比重為P(0<P<=1),而系統一共有C個CPU,為了讓CPU跑滿而又不過載,線程池的大小經驗公式 T = C / P。在此,T只是一個參考,考慮到P的估計並不是很准確,T的最佳估值可以上下浮動50%。

這個經驗公式的原理很簡單,T個線程,每個線程占用P的CPU時間,如果剛好占滿C個CPU,那么必有 T * P = C。

下面驗證一下邊界條件的正確性:

假設C = 8,P = 1.0,線程池的任務完全是密集計算,那么T = 8。只要8個活動線程就能讓8個CPU飽和,再多也沒用了,因為CPU資源已經耗光了。

假設C = 8,P = 0.5,線程池的任務有一半是計算,有一半在等IO上,那么T = 16.考慮操作系統能靈活,合理調度sleeping/writing/running線程,那么大概16個“50%繁忙的線程”能讓8個CPU忙個不停。啟動更多的線程並不能提高吞吐量,反而因為增加上下文切換的開銷而降低性能。

如果P < 0.2,這個公式就不適用了,T可以取一個固定值,比如 5*C。另外公式里的C不一定是CPU總數,可以是“分配給這項任務的CPU數目”,比如在8核機器上分出4個核來做一項任務,那么C=4

文章如何合理設置線程池大小里面提到了一個公式:

最佳線程數目 = ((線程等待時間+線程CPU時間)/線程CPU時間 )* CPU數目

比如平均每個線程CPU運行時間為0.5s,而線程等待時間(非CPU運行時間,比如IO)為1.5s,CPU核心數為8,那么根據上面這個公式估算得到:((0.5+1.5)/0.5)*8=32。這個公式進一步轉化為:

最佳線程數目 = (線程等待時間與線程CPU時間之比 + 1)* CPU數目

可以得出一個結論:
線程等待時間所占比例越高,需要越多線程。線程CPU時間所占比例越高,需要越少線程。

 

workQueue:保存任務的阻塞隊列,與線程池的大小有關:

  當運行的線程數少於corePoolSize時,在有新任務時直接創建新線程來執行任務而無需再進隊列
  當運行的線程數等於或多於corePoolSize,在有新任務添加時則選加入隊列,不直接創建線程
  當隊列滿時,在有新任務時就創建新線程


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM