监视器与互斥体

Posted

技术标签:

【中文标题】监视器与互斥体【英文标题】:Monitor vs Mutex 【发布时间】:2016-11-04 16:58:35 【问题描述】:

我读到 mutex 是一个值为 1 的信号量(二进制信号量),用于强制互斥。

我读了这个链接 Semaphore vs. Monitors - what's the difference? 这表示监视器有助于实现互斥。

谁能告诉我互斥锁和监视器之间的区别,因为它们都有助于实现相同的目标(互斥)?

【问题讨论】:

【参考方案1】:

由于您尚未指定您所谈论的操作系统或语言/库,所以让我以通用的方式回答。

从概念上讲,它们是相同的。但通常它们的实现方式略有不同

监控

通常,监视器的实现速度更快/重量更轻,因为它是为同一进程内的多线程同步而设计的。此外,它通常由框架/库本身提供(而不是请求操作系统)。

互斥体

通常,互斥体由操作系统内核提供,库/框架只是提供一个接口来调用它。这使得它们重量级/速度更慢,但它们在不同进程的线程中工作。操作系统还可能提供按名称访问互斥锁的功能,以便在单独的可执行文件的实例之间轻松共享(而不是使用只能由fork 使用的句柄)。

【讨论】:

似乎安静的相反(性能方面):japgolly.blogspot.bg/2012/04/ruby-mutex-reentrancy.html @akostadinov 我不知道 ruby​​ 对此有何评论。甚至不确定用于此基准测试的代码是否可靠。也许 Ruby 是我所做的一般性陈述的异常值? Joseph Albahari 有一些 Comparison of Locking Constructs in C#,这似乎更符合我的主张 没有注意到这个问题不是 ruby​​ 特定的。奇怪,但我对这种奇怪并不感到惊讶。我的意思是 ruby​​ 行为与其他任何东西的差异。 您对互斥锁的定义听起来像以前所说的信号量...【参考方案2】:

Monitor 与 Mutex 不同,但它们可以被认为是相似的,因为 Monitor 构建在 Mutex 之上。为清楚起见,请参阅底部图像中的监视器描述。

监视器是一种同步结构,它允许线程同时具有互斥(使用锁)和协作,即能够让线程等待某个条件为真(使用等待集)。

换句话说,与实现锁的数据一起,每个 Java 对象在逻辑上都与实现等待集的数据相关联。锁帮助线程在共享数据上独立工作而不会相互干扰,而等待集帮助线程相互合作以实现共同目标,例如所有等待的线程都将被移动到这个等待集,一旦锁被释放,所有的线程都会得到通知。此等待集有助于在锁定 (mutex) 的额外帮助下构建监视器。

你想要的,你可以看我的回答here,可能与这个问题相关,也可能不相关。

你可以在这里找到另一个相关的讨论

Semaphore vs. Monitors - what's the difference?

【讨论】:

【参考方案3】:

不幸的是,教科书的定义并不总是与不同平台和语言使用这些术语的方式相对应。因此,要获得准确的答案,您必须指定平台和上下文。但总的来说:

mutex 是一个锁,一次只能由一个线程拥有。锁本身并不保护任何东西,但代码可以检查互斥锁的所有权,以确保某些代码部分一次只能由单个线程执行。如果一个线程想要获取互斥锁,则该线程将被阻塞,直到可用为止。

在 Java 术语中,monitor 是与对象隐式关联的互斥锁。当synchronized 关键字应用于类或方法时,会在代码周围创建一个隐式互斥锁,以确保一次只有一个线程可以执行它。这称为监视器锁定或只是监视器。

所以在 Java 中,监视器不是一个特定的对象,而是 任何 对象都有一个可用的监视器锁,它通过 synchronized 关键字调用。

synchronized 关键字也可以用于代码块,在这种情况下,要锁定的对象是明确指定的。这里有点奇怪,因为您可以使用一个对象的监视器来锁定对另一个对象的访问。

在计算机科学教科书中,您可能会遇到不同类型的监视器,Brinch-Hansen 或 Hoare-monitor,它是隐式线程安全的类或模块(如 Java 中的同步类)并且具有多个条件线程可以等待/发出信号。这是一个比 Java 监视器更高级别的概念。

C#/.NET 有类似于 Java 的监视器,但在标准库中也有一个 Mutex 类 - 这与监视器中使用的互斥锁不同。监视器锁只存在于单个进程中,而Mutex-lock 是机器范围的。因此,监视器锁适用于使对象和数据结构线程安全,但不适用于提供系统范围内对文件或设备的独占访问。

所以底线:这些术语可能意味着不同的东西,所以如果你想要一个更具体的答案,你应该指定一个特定的平台。

【讨论】:

AFAIK 监视器是互斥体和一个或多个条件变量的组合。 @pveentjer:是的,这是一个 Brinch-Hansen/Hoare-monitor,它不同于 Java 监视器。 AFAIK java monitor也是mutex + 1个条件变量的组合。

以上是关于监视器与互斥体的主要内容,如果未能解决你的问题,请参考以下文章

信号量,互斥,监视器之间的区别实现了同步

在 C++ 中使用互斥锁和条件变量实现带有信号的监视器

第20章 线程同步

为啥 AMD-CPU 有这么愚蠢的暂停时间

Java中的锁

Synchronized理解及用法