Dot-Net

多執行緒或任務並行庫

  • June 17, 2022

我有一個應用程序,它使用多執行緒同時執行 30 個獨立任務,每個任務通過 http 檢索數據,執行計算並將結果返回給 ui 執行緒。

我可以使用 TPL 執行相同的任務嗎?

TPL 是創建 30 個新執行緒並將它們分佈在所有可用核心上,還是只是將任務拆分到可用核心上並每個核心使用一個執行緒?

在這種情況下,使用 TPL 而不是多執行緒會提高性能嗎?

我相信 TPL 通常每個核心使用一個執行緒,除非您明確告訴它使用更多。它可能會檢測到什麼時候這還不夠——例如,在您的情況下,您的任務將花費大部分時間等待數據。

有什麼理由不能使用非同步 Web 抓取?我懷疑這裡不需要每個任務都有一個執行緒,甚至每個核心都不需要一個執行緒。TPL 使非同步程式的各個方面變得更容易,例如延續。

就效率而言,您的應用程序實際上是否受 CPU 限制?聽起來您需要在網路端獲得最大適當級別的並行性 - 這是需要集中精力的一點,除非計算真的很重量級。


更新 - 不是來自原作者

上面的答案一如既往地好,但可能會產生誤導,因為它在 .NET 4.0 CLR 中沒有一些重要的變化。

正如 Andras 所說,目前的 TPL 實現使用執行緒池,因此將根據需要使用盡可能多的執行緒(核心數量現在無關緊要):

任務並行庫 (TPL) 是一組新類,專門設計用於更輕鬆、更高效地在現代硬體上執行非常細粒度的並行工作負載。TPL 作為 CTP 已經單獨提供了一段時間,並且包含在 Visual Studio 2010 CTP 中,但在這些版本中,它基於自己的專用工作調度程序建構的。對於 CLR 4.0 的 Beta 1, TPL 的預設調度程序將是 CLR 執行緒池,它允許 TPL 風格的工作負載與現有的、基於 QUWI 的程式碼“玩得很好”,並允許我們線上程池——特別是執行緒注入算法,我們將在以後的文章中討論。

從:

關聯

作為一般規則,沒有什麼可以阻止 TPL 使用比核心更多(或更少)的執行緒。

為了在某種程度上使用 TPL 來控制這種情況,我的第一種方法是:確保執行緒池最大執行緒設置至少為 30,然後以最大並發級別30 並行化任務。在任務中,您可以在執行之前使用信號量啟動 CPU 密集型計算以將並發性限制為核心數。如果您不在 IIS 或 SQL 伺服器下執行,您可以並且可能希望將執行緒池執行緒的最小/最大數量設置為 30,以防止執行緒池啟發式算法過多地使用執行緒數。(當然,前提是 TPL 和執行緒池在此期間在您的應用程序中不用於其他目的。)

最佳執行緒數取決於具體情況。考慮例如您的場景:您的任務在檢索數據時不受 CPU 限制 - 它們受網路限制。開始任務時,明智的做法是增加並行度,以便同時進行下載。但是,您的計算可能受 CPU 限制。在這種情況下,減少執行緒數以使每個核心只執行一個執行緒可能會產生更好的性能。

TPL 現在基於新的CLR 執行緒池

執行緒池使用啟發式方法來決定執行緒數。

有一個關於新執行緒池的Channel9 影片有一些見解。

舊執行緒池的啟發式和一些關於新執行緒池的資訊可以在這裡找到*(最後一段“未來會怎樣?”)*

算法和數字在 CLR 的不同版本中會發生變化。

未來也可能如此。

關於並發級別的文章有很多,我遇到的一個是here

引用自:https://stackoverflow.com/questions/2521840