首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 平行程式設計概述:輕量級同步原語詳細解析

     編輯:關於C#

背景

存取共享資料時需顯式同步。.NET Framework 4 在 System.Threading 提供 6 個輕量級同步原語,避免昂貴鎖機制,適用於等待時間短的情境:

  • Barrier:多工作依階段協同,屏障同步。
  • CountdownEvent:計數歸零觸發信號。
  • ManualResetEventSlim:手動重置事件,短等待效能優於 ManualResetEvent。
  • SemaphoreSlim:限制並發存取數,效能優於 Semaphore。
  • SpinLock:自旋鎖,適合極短關鍵區。
  • SpinWait:自旋等待支援。

Barrier:階段式協同工作

範例:模擬 N 人各煮 3 次飯,步驟:打水→淘米→放鍋→蓋蓋→生火。每階段所有人完成才能進入下一階段。

private static Barrier _barrier = new Barrier(_participants, (b) => 
  Console.WriteLine("當前階段:{0}", b.CurrentPhaseNumber));

// 工作方法中每步驟結束呼叫
_barrier.SignalAndWait();

結果:並發版本保證階段順序且大幅降低總耗時(圖表對比)。ContinueWhenAll 在所有任務完成後執行延續邏輯(統計耗時、釋放資源)。

Barrier 超時與異常處理

if (!_barrier.SignalAndWait(2000)) // 等待 2 秒
  throw new OperationCanceledException("等待超時");

try { _barrier.SignalAndWait(); }
catch (Exception ex) { /* 記錄異常 */ continue; }

任務完成後檢查 task.Exception 輸出異常報表。

鎖特性與 Monitor

  • 互斥:一次單一執行緒持有鎖,保證資料一致性。
  • 可見性:釋放鎖前的修改,後續取得鎖的執行緒可看見。

Monitor.Enter/Exit 與 lock 等價,但 Monitor 提供 TryEnter(支援逾時)、Wait/Pulse/PulseAll 等進階控制。

SpinLock:高效能自旋鎖

適用於關鍵區極短、競爭不激烈情境。注意:不可宣告為 readonly 欄位,否則每次存取取得新副本導致鎖失效。

volatile 關鍵字

「輕量級 lock」:保證可見性(最新值可見),但不具原子性。適用於讀多寫少、簡單旗標同步,效能優於鎖且不阻塞。

ManualResetEventSlim

ManualResetEventSlim mres = new ManualResetEventSlim(false);
Task observer = Task.Factory.StartNew(() => {
  mres.Wait();
  while (true) { if (mres.IsSet) { /* 執行工作 */ } Thread.Sleep(100); }
});
Thread.Sleep(2000);
mres.Set();   // 釋放等待
mres.Reset(); // 重置為無信號
mres.Set();

結合自旋與核心等待,短等待高效能。跨進程/AppDomain 需用 ManualResetEvent。

SemaphoreSlim

SemaphoreSlim ss = new SemaphoreSlim(3); // 最大並發 3
ss.Wait();   // 進入,計數 -1
ss.Release(); // 離開,計數 +1
ss.Release(3); // 一次釋放 3

計數信號量協調資源存取,不保證進入順序。短等待低開銷。

CountdownEvent

CountdownEvent cde = new CountdownEvent(3); // 初始計數 3
cde.Signal(); // 計數 -1
cde.Wait();   // 阻塞至計數歸零
cde.Reset();  // 重置為初始計數
cde.Reset(5); // 重置為指定計數
cde.AddCount(2); // 增加計數

適用於 Fork/Join 模式追蹤動態任務完成,開銷小於 Task.WaitAll。可重複重置實現多輪計數。

作者與出處

作者:釋迦苦僧|出處:https://www.cnblogs.com/woxpp

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved