C#多线程同步(二)【Mutex】

来源:互联网 发布:泳衣淘宝网 编辑:程序博客网 时间:2024/05/21 07:08

人来到这世上是握着手的,因为他想要很多东西;当死去的时候,手是松开的,因为想开了。


Monitor和Lock多用于锁定被调用端,而Mutex则多用锁定调用端。

Framework中已经为我们提供了三个加锁的机制,分别是Monitor类、Lock关键字和Mutex类。其中Lock关键词用法比较简单,Monitor类和Lock的用法差不多。这两个都是锁定数据或是锁定被调用的函数。而Mutex则多用于锁定多线程间的同步调用。简单的说,Monitor和Lock多用于锁定被调用端,而Mutex则多用锁定调用端。

lock (this){ //Do something}

或者是用Monitor也是一样的,如下:

Monitor.Enter(this);//Do somethingMonitor.Exit(this); //(Monitor的好处是可以用TryEnter(this,timeout))

这就是锁定被调用函数的特性,即只能保证每次被一个线程调用,这就是所谓的强占式。同一时间只能有同一Thread Lock 代码块(这里是this),其他Thread执行到此代码块去要等待占用的Thread release代码块。需要注意的是,本Thread是可以多次Lock代码块的。

Mutex:

mutex.WaitOne();//Do somethingmutex.ReleaseMutex();

Mutex只能互斥线程间的调用,但是不能互斥本线程的重复调用,即thread1中waitOne()只对thread2中的waitOne()起到互斥的作用,但是thread1并不受本wainOne()的影响,可以调用多次,只是在调用结束后调用相同次数的ReleaseMutex()就可以了。

互斥体Mutex和事件对象EventWaitHandler属于内核对象,利用内核对象进行线程同步,线程必须要在用户模式和内核模式间切换,所以一般效率很低,但利用互斥对象和事件对象这样的内核对象,可以在多个进程中的各个线程间进行同步。

互斥体Mutex类似于一个接力棒,拿到接力棒的线程才可以开始跑,当然接力棒一次只属于一个线程(Thread Affinity),如果这个线程不释放接力棒(Mutex.ReleaseMutex),那么没办法,其他所有需要接力棒运行的线程都知道能等着看热闹。

Mutex是一个令牌,当一个线程拿到这个令牌时运行,另外想拿到令牌的线程就必须等待,直到拿到令牌的线程释放令牌。没有所有权的线程是无法释放令牌的。

Mutex(false,”string”)中的string是令牌的关键,或者可以叫令牌名,因为Mutex是跨进程的,整个系统中只会有唯一的令牌存在所以,也就是说你在一个应用程序中的一个线程中得到了Mutex的所有权,那在另外一个线程中的另外的线程想得到他就必须要等待。


Test.cs代码:

class Test    {        //1.   Mutex是一个令牌,当一个线程拿到这个令牌时运行,另外想拿到令牌的线程就必须等待,直到拿到令牌的线程释放令牌。没有所有权的线程是无法释放令牌的。        //2.   Mutex(false,”string”)中的string是令牌的关键,或者可以叫令牌名,因为Mutex是跨进程的,整个系统中只会有唯一的令牌存在所以,也就是说你在一个应用程序中的一个线程中得到了Mutex的所有权,那在另外一个线程中的另外的线程想得到他就必须要等待。        static string MutexName = "ThreadingDemo";        public static void RunTest()        {            //创建一个Mutex对象,并且命名为ThreadingDemo              using (var m = new Mutex(false, MutexName))            {                ////等待m的释放                  if (!m.WaitOne(TimeSpan.FromSeconds(5), false))                {                    Console.WriteLine("第二个实例正在运行");                    Console.ReadLine();                }                else                {                    Console.WriteLine("运行中!");                    Console.ReadLine();                    m.ReleaseMutex();                }            }        }    }

运行结果如图:

这里写图片描述

0 0
原创粉丝点击