zoukankan      html  css  js  c++  java
  • 线程同步方式之互斥量Mutex

    互斥量和临界区非常相似,只有拥有了互斥对象的线程才可以访问共享资源,而互斥对象只有一个,因此可以保证同一时刻有且仅有一个线程可以访问共享资源,达到线程同步的目的。

    互斥量相对于临界区更为高级,可以对互斥量进行命名,支持跨进程的线程同步。互斥量是调用的Win32的API对互斥锁的操作,因此在同一操作系统下不同进程可以按照互斥锁的名称共享锁。

    正因为如此,互斥锁的操作会更好资源,性能上相对于临界区也有降低,在使用时还要多斟酌。对于进程内的线程同步使用临界区性能会更佳。

    在.Net中使用Mutex类来表示互斥量,使用实例的WaitOne()阻止线程执行至到获取Mutex对象,ReleaseMutex()释放锁资源,我们来看一下示例

    class MutexTest
        {
            //创建Mutex对象
            private static Mutex mutex = new Mutex(true, "My");
            //
            static void Main(string[] args)
            {
                Run();
                Console.ReadLine();
            }
            //模拟多线程调用
            public static void Run()
            {
                const int count = 2;
                var threads = new Thread[count];
                for (var i = 0; i < count; i++)
                {
                    var ts = new ThreadStart(UserResource);
                    var t = new Thread(ts);
                    t.Name = "thread" + (i + 1);
                    threads[i] = t;
                }
                foreach (var t in threads)
                {
                    t.Start();
                }
                //
                Console.WriteLine(string.Format("Creating thread {0} owns the Mutex.", Thread.CurrentThread.Name));
                Thread.Sleep(1000);
                mutex.ReleaseMutex();
                Console.WriteLine(string.Format("Creating thread {0} releases the Mutex.", Thread.CurrentThread.Name));
            }
            //修改共享资源值
            public static void UserResource()
            {
                mutex.WaitOne();
                Console.WriteLine(string.Format("Child thread named {0} owns the mutex.", Thread.CurrentThread.Name));
                Thread.Sleep(1000);
                mutex.ReleaseMutex();
                Console.WriteLine(string.Format("Child thread named {0} releases the mutex.", Thread.CurrentThread.Name));
            }
        }

    Mutex对象是一个全局对象,构造时可以指定name,只要name一样都认为是同一个Mutext。另外再构造时指定的第一个Bool参数表示创建Mutex对象的线程是否拥有该互斥量。

    如果是True表示拥有,必须要释放后才可以被其它线程使用。上述代码示例中就需要主线程释放Mutex。

    首先由主线程创建一个Mutex对象,并拥有该Mutex对象

    然后主线程接着执行,创建2个线程,线程内部使用WaitOne来阻止该线程继续执行,直到接收到Mutex对象释放的信号,方能获得Mutex使用权,继续执行。

    Sleep 1秒之后,主线程释放Mutex对象

    子线程WaitOne获得释放信号并抢占Mutex拥有权,获得者将进入执行资源代码,而另外的子现在要等到ReleaseMutex之后才能获得Mutex拥有权。

    在使用Mutex时WaitOne用来阻止线程的执行,直到获取到Mutex对象的拥有权。也可以指定阻止时间,超时获取Mutex拥有权失败,会继续执行后续代码,执行完毕无需释放Mutex。

    WaitOne要和ReleaseMutex成对使用,获取锁对象后要记得释放,否则会造成其它线程一直等待状态。

  • 相关阅读:
    019_linuxC++之_函数模板引入
    018_linuxC++之_抽象类的引入
    017_linuxC++之_多态的引入
    《将博客搬至CSDN》
    016_linuxC++之_多重继承
    013_linuxC++之_派生类中权限的调整
    015_linuxC++之_覆写
    014_linuxC++之_不同类型的继承
    012_linuxC++之_类的继承定义
    011_linuxC++之_继承的引入
  • 原文地址:https://www.cnblogs.com/oneheart/p/5633842.html
Copyright © 2011-2022 走看看