[轉載]C#使用Interlocked進行原子操作

来源:http://www.cnblogs.com/Scl891004X/archive/2016/12/01/6122405.html
-Advertisement-
Play Games

在C#中有多個線程同時對某個變數進行操作的時候,我們應該使用原子操作,防止多線程取到的值不是最新的值。 本文介紹了多線程中使用原子操作與不使用原子操作的不同,以及使用原子操作與使用lock鎖來保障多線程執行的唯一性的性能優劣。 ...


原文鏈接:王旭博客 » C# 使用Interlocked進行原子操作

什麼是原子操作?

原子(atom)本意是“不能被進一步分割的最小粒子”,而原子操作(atomic operation)意為”不可被中斷的一個或一系列操作” 。在C#中有多個線程同時對某個變數進行操作的時候,我們應該使用原子操作,防止多線程取到的值不是最新的值。

例如:int result = 0;
多線程A正在執行 result(0)+1
多線程B同時執行 result(0)+1

那麼最終result的結果是1還是2呢,這個就很難說了。如果在CPU中2個線程同時計算,那麼得到的結果則是1,顯然這個結果不是我們想要的。當然你可以使用lock鎖來保障多線程執行的唯一性,但是它的性能遠遠不及原子操作的方式。

使用Interlocked進行原子操作:

使用.NET提供的Interlocked類可以對一些數據進行原子操作,看起來似乎跟lock鎖一樣,但它並不是lock鎖,它的原子操作是基於CPU本身的,非阻塞的,所以要比lock的效率高。

下麵使用C#代碼進行演示了原子操作:

 1 class Program
 2  {
 3      //全局變數
 4      private static int _result;
 5 
 6      //Main方法
 7      static void Main(string[] args)
 8      {
 9          //運行後按住Enter鍵數秒,對比使用Interlocked.Increment(ref _result);與 _result++;的不同
10         while (true)
11          {
12              Task[] _tasks = new Task[100];
13              int i = 0;
14 
15              for (i = 0; i < _tasks.Length; i++)
16              {
17                  _tasks[i] = Task.Factory.StartNew((num) =>
18                 {
19                     var taskid = (int)num;
20                     Work(taskid);
21                 }, i);
22              }
23 
24              Task.WaitAll(_tasks);
25              Console.WriteLine(_result);
26 
27              Console.ReadKey();
28          }
29      }
30 
31      //線程調用方法
32      private static void Work(int TaskID)
33      {
34          for (int i = 0; i < 10; i++)
35          {
36              //_result++;
37              Interlocked.Increment(ref _result);
38          }
39      }
40  }

以上代碼運行分別註釋最後兩行代碼_result++;Interlocked.Increment(ref _result);的其中一行再運行,運行後按住Enter鍵不放運行數秒,即可看出區別兩者的區別。

至此,就體現出了Interlocked的作用,本文示例源碼下載:Interlocked_Sample.

關於原子操作的其他說明:在32位CPU執行賦值指令,數據傳輸最大寬度4個位元組。所以只要在4個位元組以下讀寫操作的,32位CPU都是原子操作。所以boolint這些類型的操作本身就是原子操作。而Interlocked提供的原子操作方法則是底層進行了功能性CPU指令封裝來完成的。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 公司還用這些老家伙沒辦法,用了幾次這倆。每次用都要重新翻一下A片。 好好的A片楞是翻譯成了禪經。把這東西弄成個玄學。微軟也是吃棗藥丸。參考了@風中靈藥的blog.寫的牛逼。 還有一些公司用到的風中靈藥沒有提及,我給自己留個tip.好以後看看。有錯誤希望大家指出。雖然我不一定改。 AutoResetE ...
  • 直接上代碼,包各位看客能用!!! 1.首先請求參數的封裝 2.HttpWebRequest 封裝 HttpUploadClient類中兩個Execute2,參考網上,大都用第一個,如果上傳小文件沒問題,要是比較大(百兆以上)就會記憶體溢出,然後就用流方式。思路是一樣的 3.調用示例: 4.介面服務後臺 ...
  • 第一步:訪問:https://www.microsoft.com/zh-cn/software-download/windows10ISO/ 預設就只能下載win10,這怎麼行呢。巨硬程式員貌似沒做服務端驗證。。第二步:瀏覽器控制台輸入以下js代碼: 效果: 需要下載的就快下。指不定哪天就被封了。 ...
  • 目前chrome是我在實現webdriver時運行最穩定的瀏覽器,如何利用webdriver打開多個標簽頁和鏈接呢,到處查找得到的往往只是如何打開標簽頁。打開標簽頁很簡單,chrome瀏覽器打開標簽頁的快捷鍵是ctrl+t,那把ctrl+t的按鍵事件傳入即可,很多種實現方式,以下只列出兩種:1:Ac ...
  • 本文介紹應用程式中添加書籍的保存功能,涉及兩個功能“新增”與“修改”。異常處理的小結。 ...
  • .net初學者,有錯誤歡迎指正。大家共同進步 Response 輸出數據 Reponse對象和Request對象組成了一對發送,接受數據的對象。 發送信息:Reponse.Write("字元串"); Reponse對象最常用的方法是Write,用於向瀏覽器發送信息。使用Write方法輸出的字元串會被 ...
  • 定義一個靜態類,類中定義靜態方法,方法中參數類型前邊加上this修飾符,即可實現對this所指向類的擴展。 有點類似js中通過類的原型去擴展方法,類的實例對象就可以通過對象.方法名去調用 示例如 ...
  • 示例代碼: is a way to use packages that were not designed for that framework. Basically you tell it "Use those targets even though they don't seem to be s ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...