本文共 2273 字,大约阅读时间需要 7 分钟。
什么是Mutex
“mutex”是术语“互相排斥(mutually exclusive)”的简写形式,也就是互斥量。互斥量跟临界区中提到的Monitor很相似,只有拥有互斥对象的线程才具有访问资源的权限,由于互斥对象只有一个,因此就决定了任何情况下此共享资源都不会同时被多个线程所访问。当前占据资源的线程在任务处理完后应将拥有的互斥对象交出,以便其他线程在获得后得以访问资源。
Mutex的用途
Mutex并不适合于有相互消息通知的同步;另一方面而我们也多次提到局部Mutex应该被Monitor/lock所取代;而跨应用程序的、相互消息通知的同步由将在后面讲到的EventWaiteHandle/AutoResetEvent/ManualResetEvent承担更合适。所以,Mutex在.net中应用的场景似乎不多。不过,Mutex有个最常见的用途:用于控制一个应用程序只能有一个实例运行。
using System;using System.Threading;class MutexSample{ private static Mutex mutex = null; //设为Static成员,是为了在整个程序生命周期内持有Mutex static void Main() { bool firstInstance; mutex = new Mutex(true, @"Global\MutexSampleApp", out firstInstance); try { if (!firstInstance) { Console.WriteLine ("已有实例运行,输入回车退出……"); Console.ReadLine(); return; } else { Console.WriteLine ("我们是第一个实例!"); for (int i=60; i > 0; --i) { Console.WriteLine (i); Thread.Sleep(1000); } } } finally { //只有第一个实例获得控制权,因此只有在这种情况下才需要ReleaseMutex,否则会引发异常。 if (firstInstance) { mutex.ReleaseMutex(); } mutex.Close(); mutex = null; } }}
这是一个控制台程序,你可以在编译后尝试一次运行多个程序,结果当然总是只有一个程序在倒数计时。你可能会在互联网上找到其它实现应用程序单例的方法,比如利用 Process 查找进程名、利用Win32 API findwindow 查找窗体的方式等等,不过这些方法都不能保证绝对的单例。因为多进程和多线程是一样的,由于CPU时间片随机分配的原因,可能出现多个进程同时检查到没有其它实例运行的状况。这点在CPU比较繁忙的情况下容易出现,现实的例子比如傲游浏览器。即便你设置了只允许一个实例运行,当系统比较忙的时候,只要你尝试多次打开浏览器,那就有可能“幸运”的打开若干独立的浏览器窗口。
别忘了,要实现应用程序的单例,需要在在整个应用程序运行过程中都保持Mutex,而不只是在程序初始阶段。所以,例子中Mutex的建立和销毁代码包裹了整个Main()函数。
使用Mutex需要注意的两个细节
参考
转载地址:http://stiii.baihongyu.com/