C#之Mutex

上一篇 / 下一篇  2014-01-25 15:58:02 / 个人分类:C#

    之前有谈到过Lock和Monitor,它们主要体现了临界区,而Mutex主要体现了互斥量。互斥不仅仅能够在同一应用程序中的不同线程中实现资源的安全共享,而且还可以在不同应用程序的线程之间实现资源共享。用Mutex完全可以实现之前谈及的Lock和Monitor功能,但是有些大材小用了,并且Mutex需要调用操作系统资源,执行的开销要比Lock和Monitor大得多。所以如果只是为了实现一个应用程序中线程的同步操作,那么Lock和Monitor是最好不过的了。
    Mutex主要有以下几个函数:
1. WaitOne(timeout, bool):请求获取Mutex,一直阻塞到收到信号或限定时间超时。本质上WaitOne同Monitor.Enter()/TryEnter()等效,并不是Monitor.Wait()。因为WaitOne并不能在获取Mutex后像Monitor.Wait一样可以释放Mutex并将自己移到等待队列中。
2. ReleaseMutex():释放当前Mutex一次。Mutex每WaitOne一次,计数则加1;每ReleaseMutex一次,计数则减1。只要这个计数不为0,其他Mutex的等待者则没办法获取该Mutex。只有当前获取Mutex的才能释放该Mutex,否则会抛异常。
    Mutex必须实例化一个Mutex变量,它不像Monitor是个静态类,不能有自己的实例。Mutex多应用于进程间的同步操作,其最常使用于控制一个应用程序只有一个实例运行的场景中。下面举一实例:
class TestMutex
{
    private static Mutex mutex = null;

    static void Main()
    {
        bool firstInstance = false;
       
        // true: 创建mutex后获取初始拥有权
        // out firstInstance:是否第一次获取mutex
        mutex = new Mutex(true, @"Global\TestMutexApp",
           out firstInstance);
        try
        {
            if (!firstInstance)
            {
                Console.WriteLine("已有实例运行,过5秒后
                    自动退出...");
                for (int i = 0; i < 5; i++)
                {
                    Console.WriteLine("{0}秒", i+1);
                    Thread.Sleep(1000);
                }

                // 程序退出
                Environment.Exit(1);
                return;
            }
            else
            {
                Console.WriteLine("这是第一个实例,按回车键
                    退出...");
                Console.ReadLine();
            }
        }
        finally
        {
            // 只有第一个实例获取mutex才需要释放,否则异常
            if (firstInstance)
            {
                mutex.ReleaseMutex();
            }
           
            // 释放mutex所占用的所有资源
            mutex.Close();
            mutex = null;
        }
    }
}
    如果Mutex名称以前缀“Global\”开头,则mutex在所有终端服务器会话中均为可见;如果名称以前缀“Local\”开头,则mutex仅在创建它的终端服务器会话中可见。如果创建mutex不指定前缀,则默认采用前缀“Local\”。


TAG:

 

评分:0

我来说两句

Open Toolbar