• C# 多线程系列之Mutex使用


    互斥量是一个内核对象,它用来确保一个线程独占一个资源的访问,并且互斥量可以用于不同进程中的线程互斥访问资源。

    我们可以把Mutex看作一个出租车,乘客看作线程。乘客首先等车,然后上车,最后下车。当一个乘客在车上时,其他乘客就只有等他下车以后才可以上车。而线程与C# Mutex对象的关系也正是如此,线程使用Mutex.WaitOne()方法等待C# Mutex对象被释放,如果它等待的C# Mutex对象被释放了,或者它没有被任何对象有用,它就自动拥有这个对象,直到它调用Mutex.ReleaseMutex()方法释放这个对象,而在此期间,其他想要获取这个C# Mutex对象的线程都只有等待。

    Msdn地址:http://msdn.microsoft.com/en-us/library/system.threading.mutex(v=vs.110).aspx

    举MSDN上的例子说明:

    using System;
    using System.Threading;
    
    class Example
    {
        // Create a new Mutex. The creating thread does not own the mutex. 
        private static Mutex mut = new Mutex();
        private const int numIterations = 1;
        private const int numThreads = 3;
    
        static void Main()
        {
            // Create the threads that will use the protected resource. 
            for(int i = 0; i < numThreads; i++)
            {
                Thread newThread = new Thread(new ThreadStart(ThreadProc));
                newThread.Name = String.Format("Thread{0}", i + 1);
                newThread.Start();
            }
    
            // The main thread exits, but the application continues to 
            // run until all foreground threads have exited.
        }
    
        private static void ThreadProc()
        {
            for(int i = 0; i < numIterations; i++)
            {
                UseResource();
            }
        }
    
        // This method represents a resource that must be synchronized 
        // so that only one thread at a time can enter. 
        private static void UseResource()
        {
            // Wait until it is safe to enter, and do not enter if the request times out.
            Console.WriteLine("{0} is requesting the mutex", Thread.CurrentThread.Name);
            if (mut.WaitOne(1000)) {
               Console.WriteLine("{0} has entered the protected area", 
                   Thread.CurrentThread.Name);
    
               // Place code to access non-reentrant resources here. 
    
               // Simulate some work.
               Thread.Sleep(5000);
    
               Console.WriteLine("{0} is leaving the protected area", 
                   Thread.CurrentThread.Name);
    
               // Release the Mutex.
                  mut.ReleaseMutex();
               Console.WriteLine("{0} has released the mutex", 
                                 Thread.CurrentThread.Name);
            }
            else {
               Console.WriteLine("{0} will not acquire the mutex", 
                                 Thread.CurrentThread.Name);
            }
        }
    }
    // The example displays output like the following: 
    //       Thread1 is requesting the mutex 
    //       Thread1 has entered the protected area 
    //       Thread2 is requesting the mutex 
    //       Thread3 is requesting the mutex 
    //       Thread2 will not acquire the mutex 
    //       Thread3 will not acquire the mutex 
    //       Thread1 is leaving the protected area 
    //       Thread1 has released the mutex

    当一个线程占有Mutex后,代码就可以这样写:

     mutex.WaitOne();
     mutex.WaitOne();
     mutex.WaitOne();
     mutex.WaitOne();
    。。
    。。

    WaitOne这个方法被调用时 系统检查发现mutex没有被任何线程使用 故而将mutex分配给当前线程
    因而就算继续调用WaitOne也没有影响 因为系统发现当前线程已经占有 就直接返回了。换言之,waitOne是获取
    Mutex锁的方式。如果调用ReleaseMutex那么当前线程退出Mutex锁,其它线程便可进来申请。但是如果调用两次
    ReleaseMutex 那么由于当前线程实际上是不占有锁的 那么会抛出异常。

    所以不能这样写:

    mutex.ReleaseMutex();//如果已经占有 那么OK
    mutex.ReleaseMutex();//调用第二次直接异常

    Mutex是一个内核对象,所以,它是可以用作跨进程线程同步的。

    A进程可以如此写:

    Mutex mutex = new Mutex(true,"mutex1");

    B进程则可以如此写:

    Mutex mutex = Mutex.OpenExisting("mutex1")
    OpenExisting这个方法签名我们后面也可以经常看到,作用就是获取一个已经存在的内核对象。
    获取到之后的线程同步代码是跟单进程是一致的。

    完毕。

  • 相关阅读:
    二分查找小结
    FZU みねちゃんの修罗场(从一堆出现三次的数中找出出现两次的数)
    《C陷阱与缺陷》杂记
    HDU 1846 Brave Game(巴什博弈)
    【转载】并查集详解
    第七次作业——学末总结
    STL之vector
    fzuoop期中练习
    MFC 文件对话框
    第六次作业——利用MFC实现计算器图形界面以及简单四则运算表达式批处理
  • 原文地址:https://www.cnblogs.com/HouZhiHouJueBlogs/p/3945195.html
Copyright © 2020-2023  润新知