Lock 與 Mutex 用法差別
.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);