互斥体——Mutex

作者:追风剑情 发布于:2017-9-19 20:25 分类:C#

      互斥体(mutex)代表一个互斥的锁。互斥体有一些额外的逻辑,这造成它们比其他构造更复杂。首先,Mutex对象会查询调用线程的Int32 ID,记录是哪个线程获得了它。一个线程调用ReleaseMutex时,Mutex确保调用线程就是获取Mutex的那个线程。如若不然,Mutex对象的状态就不会改变,而ReleaseMutex会抛出一个System.ApplicationException。另外,拥有Mutex的线程因为任何原因而终止,在Mutex上等待的某个线程会因为抛出System.Threading.AbandonedMutexException异常而被唤醒。该异常通常会成为未处理的异常,从而终止整个进程。这是好事,因为线程在获取了一个Mutex之后,可能在更新完Mutex所保护的数据之前终止。如果其他线程捕捉了AbandonedMutexException,就可能试图访问损坏的数据,造成无法预料的结果和安全隐患。

示例

using System;
using System.Threading;

namespace MutexTest
{
    class Program
    {
        static void Main(string[] args)
        {

            SomeClass sc = new SomeClass();
            Thread myThread;
            Random rnd = new Random();

            for (int i = 0; i < 5; i++)
            {
                myThread = new Thread(new ThreadStart(sc.Method1));
                myThread.Name = String.Format("Thread{0}", i + 1);

                //等待一会再启动线程
                Thread.Sleep(rnd.Next(0, 1000));
                myThread.Start();
            }

            Console.ReadKey();
        }
    }

    internal class SomeClass : IDisposable
    {
        //Mutex对象维护着一个递归计数(recursion count)
        //调用1次WaiOne()计数增加1
        //调用1次ReleaseMutex()计数减少1
        //只有计数变成0,另一个线程才能成为该Mutex的所有者
        private readonly Mutex m_lock = new Mutex();

        public void Method1()
        {
            m_lock.WaitOne();
            //随便做些事情...
            Console.WriteLine("{0} Method1 do something...", Thread.CurrentThread.Name);
            Method2();//Method2递归地获取锁
            m_lock.ReleaseMutex();
        }

        public void Method2()
        {
            m_lock.WaitOne();
            //随便做些事情...
            Console.WriteLine("{0} Method2 do something...", Thread.CurrentThread.Name);
            m_lock.ReleaseMutex();
        }

        public void Dispose()
        {
            m_lock.Dispose();
        }
    }
}

运行测试

1111111.png

标签: C#

Powered by emlog  蜀ICP备18021003号-1   sitemap

川公网安备 51019002001593号