熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> ASP編程 >> 正文

.NET Framework 4並行編程的現在

2022-06-13   來源: ASP編程 

  讓我們進入 NET Framework 此版本 NET Framework 擴充了大量功能顯著降低了開發人員在應用程序中表示並行性的難度並提高了並行執行的效率 這遠遠超出了並行循環的范疇盡管如此我們仍將從這裡開始
  
  SystemThreading 命名空間在 NET Framework 中通過一個新的子命名空間得到了增強SystemThreadingTasks 此命名空間包含一個新類型 Parallel該類型公開了豐富的靜態方法用以實現並行循環和結構化派生聯結模式 作為其用法的示例請考慮前面的 for 循環

  

  

  借助 Parallel 類可以如下所示輕松實現並行化

  

  

  

  在這裡開發人員仍負責確保循環的每個迭代實際上都是獨立的但除此之外ParallelFor 構造會處理此循環的並行化的所有方面 該構造跨計算中涉及的所有基礎線程動態地對輸入范圍進行分區同時仍盡可能減小分區的開銷使其接近於靜態分區實現的開銷 該構造動態地增加和減少計算中涉及的線程數以便發現最適合給定工作負載的最佳線程數(與慣常認知不同的是最佳線程數並不總是等於硬件線程數) 該構造還提供前面演示的簡單實現中不存在的異常處理功能等等 最重要的是該構造使開發人員不必在線程的較低級別操作系統抽象層考慮並行性並且無需為工作負載分區卸載到多個核心以及高效地聯接結果而一次又一次地編寫謹小慎微的解決方案 如此開發人員便可集中時間處理更重要的工作使開發人員的工作更富收益的業務邏輯
  
  ParallelFor 還為需要更加精細地控制循環操作的開發人員提供了便利工具 通過為 For 方法提供的一個選項包開發人員可以控制循環運行所在的基礎計劃程序要使用的最大並行度以及循環外部實體用於請求在循環方便時盡早正常終止的取消標記

  

  

  

  此自定義功能突出了 NET Framework 中此並行化工作的一個目標在不使編程復雜化的情況下顯著降低開發人員利用並行性的難度同時為更加高級的開發人員提供了對處理和執行進行微調所需的工具 出於此目的還支持其他調整 ParallelFor 的其他重載使開發人員可以盡早中斷循環

  

  

  

  還有其他重載使開發人員能夠使狀態流過最終在同一基礎線程上運行的迭代從而顯著提高算法實現(如縮減)的效率例如

  

  

  

  Parallel 類不僅為整數范圍提供支持還為任意 IEnumerable 源(可枚舉序列的 NET Framework 表示形式)提供支持代碼可以對枚舉器連續地調用 MoveNext以便檢索下一個 Current 值 通過這種使用任意可枚舉內容的能力可實現任意數據集的並行處理而無論數據在內存中的表示形式如何數據源甚至可以根據需要具體化並在 MoveNext 調用到達源數據的尚未具體化部分時分頁

  

  

  

  與 ParallelFor 一樣ParallelForEach 也采用許多自定義功能但提供比 ParallelFor 更大的控制能力 例如ForEach 使開發人員可以自定義對輸入數據集進行分區的方式 這通過一組側重於分區的抽象類完成這些抽象類使並行化構造可以請求固定或可變數量的分區從而允許分區程序將這些分區抽象分派給輸入數據集並根據需要以靜態或動態方式將數據分配給這些分區

  

  

  

  ParallelFor 和 ParallelForEach 在 Parallel 類上補充提供了一個 Invoke 方法該方法接受任意數量的待調用操作並可實現基礎系統可以支持的最大並行度 通過此經典的派生聯結構造可以輕松地並行化遞歸的分割解決算法如常用的 QuickSort 示例

  

  

  

  

  盡管有了很大進步但是 Parallel 類只是可用功能的一小部分 NET Framework 中實現的更重大的並行化進步之一是引入了並行 LINQ人們將其親切地稱為 PLINQ(發音為Peelink LINQ(即語言集成查詢)是在 NET Framework 版本 中引入的 LINQ 實際包含兩方面內容對一組公開為數據集操作方法的運算符的描述以及 C# 和 Visual Basic 中用於直接在語言中表示這些查詢的上下文關鍵字 LINQ 中包含的許多運算符都基於數據庫社區多年以來所了解的等效運算包括 SelectSelectManyWhereJoinGroupBy 以及大約 個其他運算 NET Framework 標准查詢運算符 API 為這些方法定義了模式但是未定義這些運算應針對的確切數據集也未確切定義應如何實現這些運算 各種LINQ 提供程序隨後為許多不同數據源和目標環境(內存中集合SQL 數據庫對象/關系映射系統HPC Server 計算群集臨時和流數據源等等)實現此模式 最常用的提供程序之一名為 LINQ to Objects它提供以 IEnumerable 為基礎實現的全套 LINQ 運算符 這樣便可在 C# 和 Visual Basic 中實現查詢如下面的代碼段所示該代碼段從文件逐行讀取所有數據從而僅篩選出包含secret一詞的行並對這些行進行加密 最終結果是字節數組構成的可枚舉內容

  

  

  

  對於需要大量計算的查詢甚至只對於涉及大量長延遲 I/O 的查詢PLINQ 提供自動並行化功能從而實現利用端到端並行算法的完整 LINQ 運算符集 因此開發人員只需為數據源附加AsParallel()即可並行化前面的查詢

  

  

  

  與 Parallel 類一樣此模型也選擇強迫開發人員評估並行運行計算的後果 但是一旦做出並行選擇系統便會處理實際並行化分區線程限制等較低級別的細節 此外與 Parallel 一樣這些 PLINQ 查詢也可通過各種方式進行自定義 開發人員可以控制如何實現分區實際使用的並行度同步與延遲之間的權衡等

  

  

  

  這些用於循環和查詢的編程模型功能強大級別更高它們構建於同樣強大但是級別較低的一組基於任務的 API 之上以 SystemThreadingTasks 命名空間中的 Task 和 Task 類型為中心 實際上並行循環和查詢引擎屬於任務生成器依靠基礎任務基礎結構將表示的並行性映射到基礎系統中提供的資源 在其核心Task 是工作單元(或者更寬泛地說是異步單元即可能生成並在以後通過各種方式進行聯接的工作項)的表示形式 Task 提供 WaitWaitAll 和 WaitAny 方法這些方法允許同步阻止向前推進直至目標任務完成或直至向這些方法的重載提供的其他約束得到滿足(例如超時或取消標記) Task 通過其 IsCompleted 屬性支持輪詢任務是否完成更寬泛地說通過其 Status 屬性支持輪詢其生命周期處理中的更改 可能最重要的是它提供 ContinueWithContinueWhenAll 和 ContinueWhenAny 方法通過這些方法可以創建僅當完成一組特定先行任務時才安排的任務 通過此續接支持可以輕松實現許多方案從而可以在計算之間表示依賴關系以便系統可以基於這些依賴關系的滿足情況安排工作

  

  

  

  通過從 Task 派生的 Task 類可以從完成的操作傳出結果從而向 NET Framework 提供核心未來實現

  

  

  

  在所有這些模型(循環查詢和任務等)之下NET Framework 使用工作竊取方法提供對專門工作負載的更高效處理並且在默認情況下它使用爬山試探法隨時間推移改變使用的線程數以便找到最佳處理級別 試探法也內置在這些組件的各個部分之中以便在系統認為任何並行化嘗試都會導致慢於順序結果時間時自動回退到順序處理不過與前面討論的其他默認設置一樣這些試探法也可被覆蓋
  
  Task 無需僅表示計算密集型操作 它還可以用於表示任意異步操作 請考慮 NET Framework SystemIOStream 類該類提供 Read 方法用於從流中提取數據
  
  此 Read 操作是同步阻塞操作這樣便不會將進行 Read 調用的線程用於其他工作直至基於 I/O 的 Read 操作完成 為了實現更好的可伸縮性Stream 類以兩個方法的形式為 Read 方法提供了異步對應項BeginRead 和 EndReadNET Framework 誕生之初這些方法便遵循其中提供的模式該模式稱為 APM(即異步編程模型) 下面是前面代碼示例的異步版本
  
  但是這種方法會導致可組合性較差 TaskCompletionSource 類型通過使這類異步讀取操作可以公開為任務解決了此問題
  
  這樣便允許組合多個異步操作正如計算密集型示例中一樣 下面的示例同時從所有源數據流讀取數據僅當所有操作完成後才寫出到控制台
  
  除了用於啟動並行化和並發處理的機制之外NET Framework 還為任務與線程之間的進一步協調工作提供了基元 這包括一組線程安全且可伸縮的集合類型這些類型大體消除了開發人員手動同步對共享集合的訪問的需要 ConcurrentQueue 提供一個線程安全無鎖定先進先出的集合該集合可以由任意數量的生產者和任意數量的使用者同時使用 此外它還支持並發枚舉器的快照語義以便代碼即使在其他線程操作實例時也可以檢查隊列的狀態 ConcurrentStack 也類似只是它提供後進先出語義 ConcurrentDictionary 使用無鎖定和精細鎖定方法提供線程安全的字典該字典也支持任意數量的並發讀取器寫入器和枚舉器 它還提供幾個多步驟操作(如 GetOrAdd 和 AddOrUpdate)的原子實現 另一種類型 ConcurrentBag 提供使用工作竊取隊列的無序集合
  
  NET Framework 不會停止開發集合類型 Lazy 通過采用可配置的方法實現線程安全提供變量的延遲初始化 ThreadLocal 提供每線程每實例數據這些數據也可以在第一次訪問時延遲初始化 Barrier 類型實現階段化操作以便可以通過保持同步的算法進行多個任務或線程 該列表在不斷擴充並且所有內容都源自一個指導原則開發人員應無需關注其算法並行化的低級及初級方面而是讓 NET Framework 為其處理功能機制和效率細節


From:http://tw.wingwit.com/Article/program/ASP/201311/21768.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.