C 執行緒 入門 優化執行緒池

2021-10-12 17:29:22 字數 1500 閱讀 9486

優化執行緒池

執行緒池從其池中的乙個執行緒開始。分配任務後,池管理器會「注入」新執行緒以應對額外的併發工作負載(最大限制)。在足夠長時間的不活動之後,如果池管理器懷疑這樣做會導致更好的吞吐量,則可以「退出」執行緒。

您可以通過呼叫threadpool.setmaxthreads;來設定池將建立的執行緒的上限。預設值為:

32位環境中framework 4.0中的1023

在64位環境中的framework 4.0中為32768

框架3.5中的每個核心250個

framework 2.0中每個核心25個

(這些數字可能會因硬體和作業系統而異。)之所以有很多原因,是為了確保某些執行緒被阻塞(在等待某種條件(例如,來自遠端計算機的響應)時處於空閒狀態)的進度。

您還可以通過呼叫threadpool.setminthreads設定下限。下限的作用是微妙的:這是一種高階優化技術,它指示池管理器在達到下限之前不要延遲線程的分配。當執行緒被阻塞時,提高最小執行緒數可提高併發性(請參見側欄)。

預設的下限是每個處理器核心乙個執行緒-允許全部cpu利用率的最小值。但是,在伺服器環境(例如iis下的asp.net)上,下限通常要高得多-多達50個或更多。

最小執行緒數如何工作?

實際上,將執行緒池的最小執行緒數增加到x並不會實際上強制立即建立x個執行緒-執行緒僅根據需要建立。相反,它指示池管理器在需要它們時立即最多建立x個執行緒。那麼,問題是,為什麼在需要時執行緒池會延遲建立執行緒的時間呢?

答案是防止短暫的短暫活動導致執行緒的完全分配,從而突然膨脹應用程式的記憶體空間。為了說明這一點,請考慮執行乙個客戶端應用程式的四核計算機,該應用程式一次可處理40個任務。如果每個任務執行10毫秒的計算,則假設工作在四個核心之間分配,整個任務將在100毫秒內結束。理想情況下,我們希望40個任務恰好在四個執行緒上執行:

減少一點,我們就不會充分利用這四個核心。

再有,我們將浪費記憶體和cpu時間來建立不必要的執行緒。

這正是執行緒池的工作方式。只要將執行緒數與核心數進行匹配,只要有效地使用了執行緒(在這種情況下就是這樣),程式就可以在不影響效能的情況下保留較小的記憶體占用。

但是現在假設,每個任務而不是工作10毫秒,而是查詢internet,在本地cpu空閒時等待半秒以響應。池管理器的執行緒經濟策略崩潰了;現在建立更多執行緒會更好,因此所有internet查詢都可以同時發生。

幸運的是,池管理器有乙個備份計畫。如果其佇列保持靜止狀態超過半秒,它將通過建立更多執行緒(每半秒乙個)來響應,直至達到執行緒池的容量。

延遲的半秒是一把兩刃劍。一方面,這意味著一次短暫的短暫活動不會使程式突然消耗掉不必要的40 mb(或更多)記憶體。另一方面,當池中的執行緒阻塞時,例如vb.net教程查詢資料庫或呼叫webclient.downloadfile時,它可能不必要地c#教程延遲事情。因此,可以通過呼叫setminthreads來告訴池管理器不要延遲前x個執行緒的分配:

threadpool.setminthreads(50,50);

(第二個值指示要分配給i / o完成埠的執行緒數,由apm使用,具體請參見c#4.0第23章的內容。)

預設值為每個核心乙個執行緒。

優化執行緒池

執行緒池初始時其池內只有乙個執行緒。隨著任務的分配,執行緒池管理器就會向池內 注入 新執行緒來滿足工作負荷的需要,直到最大數量的限制。在足夠的非活動時間之後,執行緒池管理器在認為 一些執行緒能夠帶來更好的吞吐量時進行執行緒 可以通過呼叫threadpool.setmaxthreads方法來設定執行緒...

執行緒池入門

1.阻塞佇列 體系結構 collection queue blockqueue 重要的實現類 1.arrayblockingqueue 底層是陣列 2.linkedblockingqueue 底層是鍊錶 預設長度是 21 億 3.synchronousqueue 裡邊只能存放乙個 2.執行緒池 核心...

執行緒池執行緒數量優化設計

實際編碼過程中,不能一味的只進行執行緒池優化效能而不關注具體的設計細節。執行緒池執行緒數量需要根據實際專案中任務數量等進行乙個估算,使得系統的設計效能趨近於我們所想的方向,而不是隨便給乙個數值,但是不進行系統的最大瓶頸的控制。廢話不多說 轉個比較詳細的效能估算思路 jdk1.5中引入了強大的conc...