前言
在并發(fā)編程中,確保共享資源的同步訪問對防止數(shù)據(jù)損壞和保持數(shù)據(jù)一致性至關重要。互斥鎖(Mutex)是一種用于同步線程訪問共享資源的機制?;コ怄i確保共享資源在同一時間點,只有一個線程可以訪問,從而防止資源競爭與沖突。本文了解C#中Mutex實現(xiàn)互斥體的功能。
Mutex
Mutex 是一種同步的原語,在實現(xiàn)線程共享資源同步訪問,防止數(shù)據(jù)損壞和保持數(shù)據(jù)一致性方面起著至關重要的作用。
1、關鍵概念
擁有權:在任何給定時間內(nèi),只有一個線程可以擁有互斥鎖。擁有互斥鎖的線程,負責在使用受保護資源完成后釋放互斥鎖。
互斥狀態(tài):互斥鎖有二種狀態(tài),分別是處于有信號 (解鎖) 或非有信號 (鎖定) 狀態(tài)。嘗試獲取鎖定互斥鎖的線程將被阻止,直到它可用。
Mutex 的基本操作包括創(chuàng)建、獲取、釋放幾個基本操作。
在 C# 中,可以使用 System.Threading 命名空間的 Mutex 類創(chuàng)建 Mutex 對象。
// 創(chuàng)建一個具默認屬性的Mutex 實例 【未命名且初始所有權未獲取】
Mutex mutex = new Mutex();
// 創(chuàng)建一個命名為GlobalMutexName,但初始所有權未獲取的 Mutex實例
Mutex mutex = new Mutex(false, "Global_MutexName");
通過使用類提供的 WaitOne 方法獲取互斥鎖。
// 獲取 Mutex
mutex.WaitOne();
try
{
// 訪問共享資源
}
finally
{
mutex.ReleaseMutex();
}
通過使用類提供的 ReleaseMutex 方法釋放互斥鎖。
// 獲取Mutex
mutex.WaitOne();
try
{
// 訪問共享資源
}
finally
{
//釋放
mutex.ReleaseMutex();
}
2.4、為互斥鎖命名
在創(chuàng)建 Mutex 時可以指定互斥鎖名稱,通過互斥鎖名稱可以在不同的進程之間共享同一個 Mutex 實例。在跨進程同步的應用場景中互斥鎖名稱非常有用。
bool createdMutex;
using (Mutex mutex = new Mutex(false, "Global_MutexName", out createdNew))
{
if (!createdMutex)
{
Console.WriteLine("Mutex 已存在,可能已有另一個實例在運行。");
}
// 請求獲取 Mutex
mutex.WaitOne();
try
{
// 訪問共享資源
}
finally
{
// 釋放 Mutex
mutex.ReleaseMutex();
}
}
參考命名
建議使用 Global_ 前綴表示全局、Local_ 前綴表示當前,通過命名前綴以明確 Mutex 的作用范圍。
2.5、使用具有超時的互斥鎖(Mutex)
我們可以在嘗試獲取互斥鎖時指定超時,以避免無限期阻塞。if (mutex.WaitOne(TimeSpan.FromSeconds(8)))
{
try
{
// 訪問共享資源
}
finally
{
mutex.ReleaseMutex();
}
}
else
{
// 處理超時情況
}
3、注意事項
確保 Mutex 對象釋放:可使用 try...finally 語句塊在訪問結束后確保釋放 Mutex,避免死鎖;
避免長時間持有 Mutex:盡量縮短持有 Mutex 的時間,減少線程等待時間,提高性能;
做好異常處理:由于在獲取或釋放 Mutex 時可能會拋出異常,所以需做好異常處理;
避免互斥鎖名稱重復:互斥鎖名命名時,應確保其唯一性,避免與其他應用程序的 Mutex 沖突;
示例
1、在多線程應用程序中寫入文件
namespace Fountain.WinConsole.MutexDemo
{
internal class Program
{
private static Mutex fileMutex = new Mutex();
/// <summary>
/// 程序入口
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
// 啟動多個線程
for (int i = 0; i < 5; i++)
{
Thread thread = new Thread(new ParameterizedThreadStart(WriteToFile));
thread.Name = $"線程-{i + 1}";
thread.Start("寫入文件的內(nèi)容");
}
Console.ReadKey();
}
/// <summary>
/// 寫入文件
/// </summary>
/// <param name="writeContent"></param>
public static void WriteToFile(object writeContent)
{
// 獲取互斥鎖時指定超時
if (fileMutex.WaitOne(TimeSpan.FromSeconds(8)))
{
try
{
Console.WriteLine($"{Thread.CurrentThread.Name} 獲得 Mutex。正在訪問共享資源...");
Thread.Sleep(400);
Console.WriteLine($"{Thread.CurrentThread.Name} 訪問完畢。");
}
finally
{
fileMutex.ReleaseMutex();
Console.WriteLine($"{Thread.CurrentThread.Name} 釋放了 Mutex。");
}
}
else
{
Console.WriteLine($"{Thread.CurrentThread.Name} 處理超時情況。");
}
}
}
}
小結
Mutex 可以有效避免同步線程數(shù)據(jù)競爭和資源沖突,提高應用程序的穩(wěn)定性和可靠性。通過了解 Mutex,并通過正確使用Mutex,才能有效地管理并發(fā)訪問,確保程序的正確性和穩(wěn)定性。希望本文能給您帶來幫助,如有不到之處,請多多包涵。
該文章在 2024/11/4 10:28:01 編輯過