簡要分析任務與執行緒池

2021-07-22 17:17:23 字數 1918 閱讀 5100

說執行緒還是任務,我們都不可避免的要討論下執行緒池,然而在.net 4.0以後,執行緒池引擎考慮了未來的擴充套件性,已經充分利用多核微處理器

架構,只要在可能的情況下,我們應該盡量使用task,而不是執行緒池。

首先看一下task的結構

從圖中我們可以看出task.factory.startnew()貌似等同於用threadpool.queueuserworkitem()建立,但是請注意,我是用tpl的形式

使用執行緒池,要知道task出現以後,一直標榜著以更少的工作量,更低的效能消耗來pk原始執行緒。

這裡簡要的分析下clr執行緒池,其實執行緒池中有乙個叫做「全域性佇列」的概念,每一次我們使用queueuserworkitem的使用都會產生乙個

「工作項」,然後「工作項」進入「全域性佇列」進行排隊,最後執行緒池中的的工作執行緒以fifo的形式取出,效果圖類似如下:

這裡要值得一提的是,在.net 4.0之後「全域性佇列」採用了無鎖演算法,相比以前版本鎖定「全域性佇列」帶來的效能瓶頸有了很大的改觀。那麼任務

委託的執行緒池不光有「全域性佇列」,而且每乙個工作執行緒都有」區域性佇列「,效果圖如下

我們的第一反應肯定就是「區域性佇列「有什麼好處,可以考慮這樣的情況,當我們new乙個task的時候「工作項」就會進去」全域性佇列」,如果我們的

task執行的非常快,那麼「全域性佇列「就會fifo的非常頻繁,那麼有什麼辦法緩解呢?當我們的task在巢狀的場景下,「區域性佇列」就要產生效果了,

比如我們乙個task裡面有3個task,那麼這3個task就會存在於「區域性佇列」中。

從圖中可以看到,其實「區域性佇列「起到了乙個分流的作用,也叫做」任務內聯化「,」區域性佇列「採用的是」lifo"的形式,其實這樣的形式也是

為了提公升效能之用,因為run3送到「區域性佇列」中時可能還存在cpu的快取記憶體中,所以從「區域性佇列」中取出來相對來說更快一點,最後的效

果就是run3要理論上優先於run2,run1先執行。

現在我們再來考慮這樣一種情況,比如有兩個人,乙個人幹完了分配給自己的所有活,而另乙個人卻還有很多的活,從人情上說,閒的人應

該接手點忙的人的活,同樣,對應圖中「執行緒2「跑完了「區域性佇列」中的所有任務,並且同時發現」全域性佇列「中已經沒有可以跑的」任務「了,然而

「執行緒1」裡面還有run1,run2,run3,那麼此時「執行緒2」採用「fifo」的形式竊取「執行緒1」裡面的任務。

從上面種種情況我們看到,這些分流和負載都是普通threadpool.queueuserworkitem所不能辦到的,所以說在.net 4.0之後,我們

盡可能的使用tpl,拋棄threadpool。

執行緒池任務增長過程分析

執行緒緩衝佇列 private static blockingqueuebqueue new arrayblockingqueue 10 核心執行緒數 private static final int size core pool 5 執行緒池維護執行緒的最大數量 private static fi...

執行緒池概念,任務

問題 執行緒是寶貴的記憶體資源,單個執行緒約佔1mb空間,過多分配易造成記憶體溢位 頻繁的建立及銷毀執行緒會增加虛擬機器 頻率 資源開銷,造成程式效能下降 執行緒池 執行緒容器,可設定執行緒分配的數量上限 將預先建立的執行緒物件存入池中,並重用執行緒池中的執行緒物件 避免頻繁的建立和銷毀 將任務提交...

多工 執行緒池 攜程池

多工 執行緒池 from queue import queue from multiprocessing.dummy import pool 資料佇列 self.data queue queue self.pool pool def run more task self,func,count 1 把...