說執行緒還是任務,我們都不可避免的要討論下執行緒池,然而在.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。
8天玩轉並行開發 第七天 簡要分析任務與執行緒池
說執行緒還是任務,我們都不可避免的要討論下執行緒池,然而在.net 4.0以後,執行緒池引擎考慮了未來的擴充套件性,已經充分利用多核微處理器 架構,只要在可能的情況下,我們應該盡量使用task,而不是執行緒池。首先看一下task的結構 從圖中我們可以看出task.factory.startnew 貌...
8天玩轉並行開發 第七天 簡要分析任務與執行緒池
說執行緒還是任務,我們都不可避免的要討論下執行緒池,然而在.net 4.0以後,執行緒池引擎考慮了未來的擴充套件性,已經充分利用多核微處理器 架構,只要在可能的情況下,我們應該盡量使用task,而不是執行緒池。首先看一下task的結構 從圖中我們可以看出task.factory.startnew 貌...
實習第七天
昨天經理說今天會刮颱風,所以我們要求停課比較好,畢竟我是乙個非常熱愛生命的人,這絕對不是因為我小時候差點被颱風刮走,真的不是因為這個!可是今天一大早,天氣很涼快,可是再如何涼快,還是沒有暴風雨即將來臨的感覺,為此我們捶胸頓足,為什麼停課,停課也不得不去,因為我們還得以實習生的身份過去,說起這ppt,...