c# mutex monitor

什么是Mutex

  “mutex”是术语“互相排斥(mutually exclusive)”的简写形式,也就是互斥量。互斥量跟临界区中提到的Monitor很相似,只有拥有互斥对象的线程才具有访问资源的权限,由于互斥对象只有一个,因此就决定了任何情况下此共享资源都不会同时被多个线程所访问。当前占据资源的线程在任务处理完后应将拥有的互斥对象交出,以便其他线程在获得后得以访问资源。互斥量比临界区复杂,因为使用互斥不仅仅能够在同一应用程序不同线程中实现资源的安全共享,而且可以在不同应用程序的线程之间实现对资源的安全共享。.Net中mutex由Mutex类来表示。

先绕一小段路

  在开始弄明白Mutex如何使用之前,我们要绕一小段路再回来。

  读书的时候,大家接触互斥量、信号量这些玩意儿应该是在《操作系统》这一科。所以,其实这些玩意儿出现的原由是作为OS功能而存在。来看看Mutex的声明:

[ComVisibleAttribute(true)]
public sealed class Mutex : WaitHandle

  • 类上有个属性:ComVisibleAttribute(true),表明该类成员对COM成员公开。不去管它,只要知道这玩意儿跟COM有关系了,那大概跟Windows关系比较密了;
  • Mutex它有个父类:WaitHandle

  于是我们不得不再走远一些,看看WaitHandel的声明:

[ComVisibleAttribute(true)]
public abstract class WaitHandle : MarshalByRefObject, IDisposable

  WaitHandle实现了一个接口,又继承了一个父类。IDisposable在C#线程同步(2)- 临界区&Monitor关于Using的题外话中已简单提到,这里就不再多说了。看看它的父类MarshalByRefObject

MarshalByRefObject 类
允许在支持远程处理的应用程序中跨应用程序域边界访问对象。

……

备注
应用程序域是一个操作系统进程中一个或多个应用程序所驻留的分区。同一应用程序域中的对象直接通信。不同应用程序域中的对象的通信方式有两种:一种是跨应用程序域边界传输对象副本,一种是使用代理交换消息。

MarshalByRefObject 是通过使用代理交换消息来跨应用程序域边界进行通信的对象的基类。……

  好啦,剩下的内容不用再看,否则就绕得太远了。我们现在知道Mutex是WaitHandle的子类(偷偷地告诉你,以后要提到的EventWaitHandle、信号量Semaphore也是,而AutoResetEvent和ManualResetEvent则是它的孙子),而WaitHandle又继承自具有在操作系统中跨越应用程序域边界能力的MarshalByRefObject类。所以我们现在可以得到一些结论:

  • Mutex是封装了Win32 API的类,它将比较直接地调用操作系统“对应”部分功能;而Monitor并没有继承自任何父类,相对来说是.Net自己“原生”的(当然.Net最终还是要靠运行时调用操作系统的各种API)。相较于Monitor,你可以把Mutex近似看作是一个关于Win32互斥量API的壳子。
  • Mutex是可以跨应用程序/应用程序域,因此可以被用于应用程序域/应用程序间的通信和互斥;Monitor就我们到目前为止所见,只能在应用程序内部的线程之间通信。其实,如果用于锁的对象派生自MarshalByRefObject,Monitor 也可在多个应用程序域中提供锁定。
  • Mutex由于需要调用操作系统资源,因此执行的开销比Monitor大得多,所以如果仅仅需要在应用程序内部的线程间同步操作,Monitor/lock应当是首

 

https://blog.csdn.net/wuan584974722/article/details/102682246

posted @ 2022-11-24 16:47  CNHK19  阅读(23)  评论(0编辑  收藏  举报