使用互斥体(Mutex)实现同步
互斥体是操作系统内同步线程的内核对象,有相应的 Win32 函数来操作互斥体对象。
在.NET 中,Mutex
类封装了所有互斥体的操作。
Mutex
类型和Monitor
类型(lock
)的区别:
使用
Mutex
的效率非常低,相对于Monitor
类型等线程同步机制来说,操作系统互斥体的效率要慢 10 倍以上。操作系统的互斥体对系统上的所有进程都有效,也就是说它是跨进程的。
点击查看代码
cs
using System;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading;
namespace UseMutex
{
/// <summary>
/// 这里测试 Mutex 的作用,程序本身是单线程的
/// 但最终测试时将多个进程同时执行
/// </summary>
class Program
{
const string _testFile = "D:\\testMutex.txt";
/// <summary>
/// 这个互斥体可以保证所有进程得到同步
/// </summary>
static Mutex mutex = new Mutex(false, "TestMutex");
/// <summary>
/// 测试互斥体
/// </summary>
/// <param name="args"></param>
static void Main(string args)
{
// 留出时间来启动其它进程
Thread.Sleep(3 * 1000);
DoWork();
mutex.Close();
Console.Read();
}
/// <summary>
/// 往文件里写连续的内容
/// </summary>
static void DoWork()
{
long d1 = DateTime.Now.Ticks;
// 进入互斥
mutex.WaitOne();
long d2 = DateTime.Now.Ticks;
Console.WriteLine("经过{0}个 Tick 进程后{1}得到互斥体,进入临界区代码。",
(d2-d1).ToString(),
Process.GetCurrentProcess().Id.ToString());
try
{
if (!File.Exists(_testFile))
{
using (FileStream fs = File.Create(_testFile))
{ }
}
for (int i = 0; i < 5; i++)
{
using (FileStream fs = File.Open(_testFile, FileMode.Append))
{
string content = "【进程" + Process.GetCurrentProcess().Id.ToString() + "】:" + i.ToString() + "\r\n";
byte data = Encoding.Default.GetBytes(content);
fs.Write(data, 0, data.Length);
Thread.Sleep(300);
}
}
}
catch (Exception)
{
throw;
}
finally
{
// 退出互斥
mutex.ReleaseMutex();
}
}
}
}
同时执行 3 个进程时的输出结果:
点击查看输出结果
【进程2336】:0
【进程2336】:1
【进程2336】:2
【进程2336】:3
【进程2336】:4
【进程7256】:0
【进程7256】:1
【进程7256】:2
【进程7256】:3
【进程7256】:4
【进程11716】:0
【进程11716】:1
【进程11716】:2
【进程11716】:3
【进程11716】:4