聊透多線程編程-線程互斥與同步-9.C# 線程互斥實現方式

目錄

1. 鎖機制 (Locking Mechanisms)

(1)?lock?關鍵字

(2)?Monitor?類

2. 跨進程互斥機制

3. 信號量機制

(1)?Semaphore?和?SemaphoreSlim

4. 讀寫鎖機制

(1)?ReaderWriterLockSlim

5. 原子操作機制

(1)?Interlocked?類

6. 自旋鎖機制

(1)?SpinLock


線程互斥是一種保證在同一時刻只有一個線程能夠訪問共享資源的機制。它是一種排他性的訪問控制,目的是防止多個線程同時對共享資源進行讀寫操作而導致的數據不一致或其他錯誤。比如多個線程同時對一個銀行賬戶進行取款操作,如果不進行互斥控制,就可能出現賬戶余額錯誤的情況。

在 .NET 中,線程互斥(Mutual Exclusion)有多種實現方式,以下是 .NET 中常見的線程互斥實現方式:

實現方式

特點

使用場景

lock關鍵字

簡單易用,自動管理鎖

進程內同步

Monitor類

更細粒度控制鎖

顯式控制鎖的場景

Mutex類

支持跨進程

多進程間同步

信號量Semaphore?

限制最大并發數

控制資源訪問數量

讀寫鎖

ReaderWriterLockSlim

允許多線程同時讀,但只允許一個線程寫

讀多寫少的場景

Interlocked類

原子操作,高效

簡單數值操作

自旋鎖SpinLock

自旋等待鎖,避免上下文切換

短時間臨界區

根據具體需求選擇合適的線程互斥機制,能夠有效提升程序的性能和可靠性。


1. 鎖機制 (Locking Mechanisms)

(1)?lock?關鍵字

  • 原理:?lock?是 C# 中的一個語法糖,它實際上是調用了?Monitor.Enter?和?Monitor.Exit?方法來實現的。當一個線程執行到?lock?語句塊時,它會嘗試獲取鎖對象上的排他鎖。如果成功獲取,則進入臨界區執行代碼;否則,該線程將被阻塞直到鎖可用。
  • 特點:
    • 簡單易用,適用于單一應用程序域內的線程同步。
    • 自動處理異常情況下的鎖釋放。
  • 示例:
private readonly object _lockObject = new object();public void CriticalSection()
{lock (_lockObject){// 訪問共享資源的代碼}
}

(2)?Monitor?類

  • 原理:?Monitor?提供了比?lock?更靈活的同步機制,允許手動控制進入和退出臨界區。通過調用?Monitor.Enter?獲取鎖,Monitor.Exit?釋放鎖。此外,還支持條件變量(Wait,?Pulse,?PulseAll)以實現更復雜的同步邏輯。
  • 特點:
    • 支持超時等待獲取鎖的能力。
    • 可以與條件變量一起使用,支持復雜的同步模式。
  • 示例:
private readonly object _lockObject = new object();public void CriticalSection()
{try{Monitor.Enter(_lockObject);// 訪問共享資源的代碼}finally{Monitor.Exit(_lockObject);}
}


2. 跨進程互斥機制

(1)?Mutex?類

  • 原理:?Mutex?是一種內核級別的同步對象,可以用于跨進程的線程同步。當一個線程獲取了?Mutex?對象的所有權時,其他線程會被阻塞,直到該線程釋放?Mutex。
  • 特點:
    • 支持跨進程同步。
    • 性能較?lock?和?Monitor?稍低,因為它是內核對象。
  • 示例:
using System.Threading;private static Mutex _mutex = new Mutex();public void CriticalSection()
{_mutex.WaitOne(); // 獲取鎖try{// 訪問共享資源的代碼}finally{_mutex.ReleaseMutex(); // 釋放鎖}
}


3. 信號量機制

(1)?Semaphore?和?SemaphoreSlim

  • 原理:?信號量是一種允許多個線程同時訪問共享資源的同步機制,但限制最大并發數。Semaphore?支持跨進程,而?SemaphoreSlim?是輕量級版本,僅限于當前進程內使用。
  • 特點:
    • Semaphore?支持跨進程同步。
    • SemaphoreSlim?性能更高,適合單進程場景。

示例:?(SemaphoreSlim)

using System.Threading;private static SemaphoreSlim _semaphore = new SemaphoreSlim(1); // 最大并發數為 1public async Task CriticalSectionAsync()
{await _semaphore.WaitAsync();try{// 訪問共享資源的代碼}finally{_semaphore.Release();}
}


4. 讀寫鎖機制

(1)?ReaderWriterLockSlim

  • 原理:?ReaderWriterLockSlim?是一種優化的讀寫鎖,允許多個線程同時讀取共享資源,但只允許一個線程寫入資源。通過?EnterReadLock、EnterWriteLock?和?EnterUpgradeableReadLock?方法分別管理讀鎖、寫鎖和可升級的讀鎖。
  • 特點:
    • 適合讀多寫少的場景。
    • 提高了讀操作的并發性能。
  • 示例:
private static ReaderWriterLockSlim _rwLock = new ReaderWriterLockSlim();public void ReadOperation()
{_rwLock.EnterReadLock();try{// 讀取共享資源的代碼}finally{_rwLock.ExitReadLock();}
}public void WriteOperation()
{_rwLock.EnterWriteLock();try{// 寫入共享資源的代碼}finally{_rwLock.ExitWriteLock();}
}


5. 原子操作機制

(1)?Interlocked?類

  • 原理:?Interlocked?提供了一些原子操作方法,用于對簡單數據類型(如整數)進行線程安全的操作。這些操作在硬件級別上保證了原子性,無需顯式加鎖。
  • 特點:
    • 高效,無需顯式加鎖。
    • 適用于簡單的數值操作。
  • 示例:
using System.Diagnostics.Metrics;private int _counter = 0;public void IncrementCounter()
{Interlocked.Increment(ref _counter);
}public void DecrementCounter()
{Interlocked.Decrement(ref _counter);
}


6. 自旋鎖機制

(1)?SpinLock

  • 原理:?SpinLock?是一種自旋鎖,線程會不斷循環檢查鎖是否可用,而不是進入等待狀態。這種方式避免了上下文切換開銷,但在長時間鎖定時會浪費 CPU 資源。
  • 特點:
    • 適合非常短的臨界區。
    • 避免上下文切換的開銷。
  • 示例:
using System.Threading;private SpinLock _spinLock = new SpinLock();public void CriticalSection()
{bool lockTaken = false;try{_spinLock.Enter(ref lockTaken);// 訪問共享資源的代碼}finally{if (lockTaken)_spinLock.Exit();}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/76343.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/76343.shtml
英文地址,請注明出處:http://en.pswp.cn/web/76343.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

eNSP無法啟動AR報錯碼40,而且按照eNSP幫助手冊排查都沒用,我的處理方法【自己存檔版】

問題: 已經嘗試過eNSP的幫助手冊,發現都沒用! eNSP啟動AR設備報錯碼40且常規排查無效時,可嘗試以下解決方案(按優先級排序): 1. 關閉Hyper-V和Windows沙盒(我是這個問題&#xff0…

秒殺系統解決兩個核心問題的思路方法總結:1.庫存超賣問題;2.用戶重復搶購問題。

秒殺系統解決兩個核心問題 秒殺系統解決兩個核心問題:一、解決庫存超賣的核心邏輯:解釋:原子性保證: 二、如何避免重復搶購:使用 Redis 做唯一標識判斷優點: 三、流程完整梳理:四、通過數據庫建…

【集成電路版圖設計學習筆記】3.基本電路元件(MOS,電容,電阻)

一、MOSFET 在版圖設計中,要定義一個mosfet,最關鍵的層次是polysilicon(多晶硅)和active(有源區)。用有源區定義了一個矩形的區域,在這個區域內才可以形成一個有源器件,然后再用多晶…

藍橋杯之差分題型

一維差分 問題描述 給定一個長度為 nn 的序列 aa。 再給定 mm 組操作,每次操作給定 33 個正整數 l,r,dl,r,d,表示對 al~ral~r? 中的所有數增加 dd。 最終輸出操作結束后的序列 aa。 Update:由于評測機過快,n,mn,m 于 2024…

深入剖析 C/S 與 B/S 架構及網絡通信基礎

目錄 C/S 架構詳解? 概念與示例? 優點? B/S 架構詳解? 概念與示例? 優勢? 缺點? C/S 與 B/S 的區別? 架構組成? 使用場景? 開發和維護? 安全性? 網絡通信基礎? IP 地址? MAC(物理地址)? 端口? 路由器? 網關? 子網掩…

常見免殺框架的使用(3款)---【AniYaGUI1.2.0、AV_Evasion_Tool掩日、FoxBypass_V1.0】

一、AniYaGUI1.2.0免殺框架 環境:虛擬機Win10 、云服務器 工具:Xshell、CobaltStrike 項目下載地址: https://github.com/piiperxyz/AniYa 1. 安裝Go語言環境 確保Win10虛擬機安裝 Golang 且環境變量中包含 go 否則?法編譯(注…

Apache HTTPD 換行解析漏洞

漏洞介紹 CVE-2017-15715 Apache HTTPD 是一個廣泛使用的 HTTP 服務器,可以通過 mod_php 模塊來運行 PHP 網頁。在其 2.4.0 到 2.4.29 版本中存在一個解析漏洞,當文件名以 1.php\x0A 結尾時,該文件會被按照 PHP 文件進行解析,這…

常用開發環境/工具版本選擇(持續更新中)

操作系統:Ubuntu Server Version(LTS)Latest Sub VerRelease Time24.04(Noble Numbat)24.04.22025-02-1622.04(Jammy Jellyfish)22.04.52024-09-1120.04(Focal Fossa)20.04.62023-03-1418.04(Bionic Beaver)18.04.62021-09-1516.04.7(Xenial…

STM32 認識STM32

目錄 什么是嵌入式? 認識STM32單片機 開發環境安裝 安裝開發環境 開發板資源介紹 單片機開發模式 創建工程的方式 燒錄STM32程序 什么是嵌入式? 1.智能手環項目 主要功能有: 彩色觸摸屏 顯示時間 健康信息:心率&#…

C#核心筆記——(六)框架基礎

我們在編程時所需的許多核心功能并不是由C#語言提供的,而是由.NET Framework中的類型提供的。本節我們將介紹Framework在基礎編程任務(例如虛的等值比較、順序比較以及類型轉換)中的作用。我們還會介紹Framework中的基本類型,例如String、DateTime和Enum. 本章中的絕大部分…

AI——K近鄰算法

文章目錄 一、什么是K近鄰算法二、KNN算法流程總結三、Scikit-learn工具1、安裝2、導入3、簡單使用 三、距離度量1、歐式距離2、曼哈頓距離3、切比雪夫距離4、閔可夫斯基距離5、K值的選擇6、KD樹 一、什么是K近鄰算法 如果一個樣本在特征空間中的k個最相似(即特征空…

transient關鍵字深度解析

Java transient 關鍵字深度解析 transient(意思:瞬時的,瞬間的) 1. 核心概念 (1) 基本定義 作用:標記字段不參與序列化 適用場景: 敏感數據(如密碼、密鑰) 臨時計算字段 依賴運行時環境的字段(如Thread對象) (2) 語法示例 java public class User implements Se…

信刻電子檔案藍光光盤刻錄安全檢測長期歸檔

信刻一直致力于為檔案館、各行業檔案部門,提供跨網數據交換、電子檔案數據磁光異質備份歸檔解決方案。所研制的電子檔案光盤智能長期歸檔系統,滿足國產環境下”刻、管、存、檢、用”全生命周期管理應用需求,能夠提供一份離線歸檔、一份近線存…

Word 中“母版頁”的等效機制

Word 和 PowerPoint 不太一樣——**Word 實際上沒有像 PowerPoint 那樣的“母版頁(Master Page)”**功能。但它有1個和“母版頁”功能類似的東西,可能造成你看到的“校徽自動出現在每一頁”的現象: ? Word 中“母版頁”的等效機制…

Go:反射

為什么使用反射 在編程中,有時需編寫函數統一處理多種值類型 ,這些類型可能無法共享同一接口、布局未知,甚至在設計函數時還不存在 。 func Sprint(x interface{}) string {type stringer interface {String() string}switch x : x.(type) …

SS25001-多路復用開關板

1 概述 1.1 簡介 多路復用開關板是使用信號繼電器實現2線制的多路復用開關板卡;多路復用開關是一種可以將一個輸入連接到多個輸出或一個輸出連接到多個輸入的拓撲結構。這種拓撲通常用于掃描,適合將一系列通道自動連接到公共線路的的設備。多路復用開…

vue3 nprogress 使用

nprogress 介紹與作用 1.nprogress 是一個輕量級的進度條組件,主要用于在頁面加載或路由切換時顯示一個進度條,提升用戶體驗。它的原理是通過在頁面頂部創建一個 div,并使用 fixed 定位來實現進度條的效果 2.在 Vite Vue 3 項目中&#xf…

Jsp技術入門指南【六】jsp腳本原理及隱式對象

Jsp技術入門指南【六】jsp腳本原理及隱式對象 前言一、JSP 腳本元素1.1 聲明1.2 表達式1.3 腳本標簽 二、JSP 的隱式對象是什么三、隱式對象詳解outrequestsessionapplicationconfigexception 前言 在之前的博客中,我們已經介紹了JSP的環境搭建、編譯文件查找以及生…

vue3推薦的移動table庫

vxe-table https://gitee.com/js-class/vxe-table#https://gitee.com/link?targethttps%3A%2F%2Fvxetable.cn 文檔api https://vxetable.cn/#/component/table/other/bookkeepingVoucher 引入步驟 安裝 npm install xe-utils vxe-tablenext 在項目main.js引入 import …

HOOPS Exchange 與HOOPS Communicator集成:打造工業3D可視化新標桿!

一、概述 在工業3D開發、BIM建筑、數字孿生和仿真分析等高端應用場景中,數據格式復雜、模型體量龐大、實時交互體驗要求高,一直是困擾開發者的難題。Tech Soft 3D旗下的HOOPS Exchange和HOOPS Communicator,正是解決這類問題的黃金搭檔。二者…