Lock 與 Mutex 用法差別

这篇博客通过实例展示了 .NET 中 Lock 和 Mutex 的用法差异,以及它们在进程间互斥锁场景下的表现。测试结果显示,Mutex 能实现进程间的互斥锁,确保同一时间只有一个进程写入文件,而 Lock 无法实现此功能。Mutex 在多进程环境下能有效防止数据冲突,适合跨进程的资源同步,而 Lock 主要用于同一进程内的线程同步。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

.Net - Lock 與 Mutex 用法差別

測試兩者是否可以進程間互斥鎖

測試Mutex是否可以進程間互斥鎖:

使用兩個相同程式寫入同一個txt寫入測試,使用Mutex可以成功鎖住txt檔案
第一支程式寫入A,B英文字
第二支程式寫入C,D英文字

第一支程式架構

    
	private static ManualResetEvent resetEvent = new ManualResetEvent(false);
	private static bool flag = false;
	private Mutex mutex = new Mutex(false, "WriteFile", out flag);
	
	
	public Form1()
	{
		InitializeComponent();
		
		new Thread(WriteFile_A).Start();
		new Thread(WriteFile_B).Start();
	}

	private void WriteFile_A()
	{
	    while(true)
	    {
	        mutex.WaitOne();
	        using (FileStream fs = new FileStream("D:\\123.txt", FileMode.Append))
	        {
	            byte[] buffer = Encoding.UTF8.GetBytes("A");
	            fs.Write(buffer, 0, 1);
	        }
	        mutex.ReleaseMutex();
	    }
	    
	}
	
	private void WriteFile_B()
	{
	    while(true)
	    {
	        mutex.WaitOne();
	        using (FileStream fs = new FileStream("D:\\123.txt", FileMode.Append))
	        {
	            byte[] buffer = Encoding.UTF8.GetBytes("B");
	            fs.Write(buffer, 0, 1);
	        }
	        mutex.ReleaseMutex();
	    }
	    
	}

第二支程式

    
	private static ManualResetEvent resetEvent = new ManualResetEvent(false);
	private static bool flag = false;
	private Mutex mutex = new Mutex(false, "WriteFile", out flag);
	
	
	public Form1()
	{
		InitializeComponent();
		
		new Thread(WriteFile_C).Start();
		new Thread(WriteFile_D).Start();
	}

	private void WriteFile_C()
	{
	    while(true)
	    {
	        mutex.WaitOne();
	        using (FileStream fs = new FileStream("D:\\123.txt", FileMode.Append))
	        {
	            byte[] buffer = Encoding.UTF8.GetBytes("C");
	            fs.Write(buffer, 0, 1);
	        }
	        mutex.ReleaseMutex();
	    }
	    
	}
	
	private void WriteFile_D()
	{
	    while(true)
	    {
	        mutex.WaitOne();
	        using (FileStream fs = new FileStream("D:\\123.txt", FileMode.Append))
	        {
	            byte[] buffer = Encoding.UTF8.GetBytes("D");
	            fs.Write(buffer, 0, 1);
	        }
	        mutex.ReleaseMutex();
	    }
	    
	}

結果輸出 - 程式一、二都可以正常輸出

DBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBACDBAC

測試Lock是否可以進程間互斥鎖:

使用兩個相同程式寫入同一個txt寫入測試,使用Lock無法鎖住txt檔案
第一支程式寫入A,B英文字
第二支程式寫入C,D英文字

	private static object Lock_WriteFile = new object();
	public Form1()
	{
		InitializeComponent();
		
		new Thread(WriteFile_A).Start();
		new Thread(WriteFile_B).Start();
	}

	private void WriteFile_A()
	{
	    while(true)
	    {
	        lock(Lock_WriteFile)
	        {
		        using (FileStream fs = new FileStream("D:\\123.txt", FileMode.Append))
		        {
		            byte[] buffer = Encoding.UTF8.GetBytes("A");
		            fs.Write(buffer, 0, 1);
		        }
	        }
	    }
	    
	}
	
	private void WriteFile_B()
	{
	    while(true)
	    {
	         lock(Lock_WriteFile)
	        {
		        using (FileStream fs = new FileStream("D:\\123.txt", FileMode.Append))
		        {
		            byte[] buffer = Encoding.UTF8.GetBytes("B");
		            fs.Write(buffer, 0, 1);
		        }
	        }
	    }
	    
	}

第二支程式

    
	private static object Lock_WriteFile = new object();
	public Form1()
	{
		InitializeComponent();
		
		new Thread(WriteFile_C).Start();
		new Thread(WriteFile_D).Start();
	}

	private void WriteFile_C()
	{
	    while(true)
	    {
	        mutex.WaitOne();
	        using (FileStream fs = new FileStream("D:\\123.txt", FileMode.Append))
	        {
	            byte[] buffer = Encoding.UTF8.GetBytes("C");
	            fs.Write(buffer, 0, 1);
	        }
	        mutex.ReleaseMutex();
	    }
	    
	}
	
	private void WriteFile_D()
	{
	    while(true)
	    {
	        mutex.WaitOne();
	        using (FileStream fs = new FileStream("D:\\123.txt", FileMode.Append))
	        {
	            byte[] buffer = Encoding.UTF8.GetBytes("D");
	            fs.Write(buffer, 0, 1);
	        }
	        mutex.ReleaseMutex();
	    }
	    
	}

結果輸出 - 只有程式二C或D輸出,程式一跳error

CDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC


原因分析:

Mutex可以跨進程間鎖IO:

Mutex可以跨進程間鎖IO,但同時直接鎖進程也會消耗較多的資源

同一支程式做多線程同工使用Lock就夠用,不需要使用Mutex

但如果整個系統下,可以使用Mutex進行互斥鎖。


Mutext是否單純用於多線程:

宣告時小技巧:

在這裡宣告Mutex的名稱時,把WriteFile改成其他名稱,Mutex就不會找系統內的名稱做鎖定。
private Mutex mutex = new Mutex(false, “WriteFile”, out flag);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值