当我在工作中进行激烈的讨论时,我会使用一只橡胶鸡,我将它放在我的办公桌上以备不时之需。拿着鸡的人是唯一可以说话的人。如果你不拿着鸡,你就不能说话。你只能表示你想要鸡肉,等到你拿到鸡后再说话。一旦你说完,你可以把鸡交还给主持人,主持人将把它交给下一个发言的人。这确保了人们不会互相交谈,并且也有自己的交谈空间。
用互斥锁替换鸡,用线程替换人,你基本上就有了互斥锁的概念。
当然,没有橡胶互斥体这样的东西。只有橡胶鸡。我的猫曾经有一只橡胶老鼠,但它们吃了。
当然,在你使用橡皮鸡之前,你需要先问问自己,你是否真的需要 5 个人在一个房间里,一个人在房间里独自完成所有工作会不会更容易。实际上,这只是扩展类比,但你明白了。
@SirYakalot,你的意思是鸡是资源,版主是互斥体?
有时一些编程概念的起源尚不清楚。新手可能会想知道为什么每个人都在谈论正则表达式。 regex 是 [reg]ular [ex]pression 的缩写,这一点并不明显。同样,mutex 是 [mut]ual [ex]clusion 的缩写。这可能会使该术语的含义更容易理解。 @TheSmurf 在他们的答案中链接到它,但出于历史目的将它添加到此处可能会很好。
有人读过“蝇王”:-) RubberChicken == Conchsparknotes.com/lit/flies/central-idea-essay/…
“当然,没有橡胶互斥体这种东西。”感谢您的澄清。
@Xetius 你可以合并吗彼得·彼得罗夫的评论进入你的答案?这将使您的答案更完整……
我在stackoverflow上见过的最好的答案,优雅。
不要混淆橡皮鸭调试.
真的,喜欢阅读解释。值得庆幸的是,当时存在这样的解释。
搞笑的比喻。
我会补充说“一般来说如果您收到橡胶鸡,您就有机会听到前任所有者在他/她/它拥有同一只橡胶鸡时所说的一切。”互斥锁通常将记忆屏障与它们的排他性同步。
我想我从来没有见过更好地使用隐喻来解释某事。你这么说,它只是通过类比立即点击。谢谢你。 …在一个人/线程被告知“包裹起来”以便下一个人/线程可以说话/执行之前,主持人/操作系统是否对鸡/互斥锁可以持有多长时间施加任何限制?相比之下,信号量(我听说过的与相互资源访问有关的另一个术语)是什么?
莎士比亚的编程。
是否存在互斥体入侵?如果没有,应该有。
互斥锁是一个穆特平时前任包容性标志。它充当一段代码的看门人,允许一个线程进入并阻止对所有其他线程的访问。这确保了被控制的代码一次只会被一个线程命中。完成后一定要释放互斥锁。 🙂
互斥锁与一段代码本身无关,它保护了一些资源。如果仅在该代码周围使用互斥锁,则该资源可能是代码段,但是,一旦您开始在代码中的多个位置使用互斥锁,您的解释就会失败。通常它也可以用来保护一些数据结构,这些数据结构可以从代码中的许多地方访问。
@paxdiablo:请允许我不同意。你可以有两段代码,一段使用互斥锁,另一段不使用。您可以从两段代码访问数据结构。互斥锁是如何保护数据结构的?它没有。您将进行数据竞争,就好像根本没有 Mutex 一样。
@Thomas,那么您的代码有错误。说互斥锁不保护数据是因为您没有在需要的地方使用互斥锁,这与说您的家庭安全性不足,因为在星期四,您将前门解锁并打开你去上班:-)
@paxdiablo:这就是我的观点:开发人员必须遵循一个约定,即他只能使用以下方式访问数据结构代码受互斥体保护。互斥锁保护代码。它不保护数据结构。如果我经常开门,我会说我的家庭安全是无用的。然后我以错误的方式实现它,就像我以错误的方式实现代码一样。
@Thomas,我怀疑它只会归结为语义。在我看来,忘记使用互斥锁来保护数据与忘记使用互斥锁来保护代码没有什么不同。您在某些时候忘记保护它,会引起欢闹:-) 我可以理解您的观点,但我必须坚持我的描述,因为通常运行相同的多个线程完全没有问题代码,因为代码本身在它们下面不会改变。只有当数据出乎意料的变化会让他们陷入困境。
穆特华尔前任包含。这是关于它的维基百科条目。
互斥锁的目的是同步两个线程。当您有两个线程尝试访问单个资源时,一般模式是让第一个代码块尝试访问以在输入代码之前设置互斥锁。当第二个代码块尝试访问时,它看到互斥锁已设置并等待直到第一个代码块完成(并取消设置互斥锁),然后继续。
显然,如何实现这一点的具体细节因编程语言而异。
当您有一个多线程应用程序时,不同的线程有时会共享一个公共资源,例如变量或类似资源。此共享源通常无法同时访问,因此需要一个构造来确保一次只有一个线程在使用该资源。
这个概念称为“互斥”(简称 Mutex),是一种确保在该区域内只允许一个线程使用该资源等的方法。
如何使用它们是特定于语言的,但通常(如果不总是)基于操作系统互斥锁。
由于范式,某些语言不需要这种结构,例如函数式编程(Haskell、ML 就是很好的例子)。
什么是互斥体?
互斥锁(实际上,术语互斥锁是互斥的缩写)也称为自旋锁,是最简单的同步工具,用于保护关键区域,从而防止竞争条件。即一个线程在进入临界区之前必须获得一个锁(在临界区中,多个线程共享一个公共变量,更新表,写入文件等),当它离开临界区时释放锁。
什么是比赛条件?
当两个或多个线程可以访问共享数据并且它们尝试同时更改它时,就会出现竞争条件。因为线程调度算法可以随时在线程之间交换,所以你不知道线程尝试访问共享数据的顺序。因此,数据更改的结果取决于线程调度算法,即两个线程都在“竞相”访问/更改数据。
现实生活中的例子:
当我在工作中进行激烈的讨论时,我会使用一只橡胶鸡,我将它放在我的办公桌上以备不时之需。拿着鸡的人是唯一可以说话的人。如果你不拿着鸡,你就不能说话。你只能表示你想要鸡肉,等到你拿到鸡后再说话。一旦你说完,你可以把鸡交还给主持人,主持人将把它交给下一个发言的人。这确保了人们不会互相交谈,并且也有自己的交谈空间。
用互斥锁替换鸡,用线程替换人,你基本上就有了互斥锁的概念。
@Xetius
C#中的用法:
此示例显示了如何使用本地 Mutex 对象来同步对受保护资源的访问。因为每个调用线程在获得互斥锁的所有权之前都会被阻塞,所以它必须调用 ReleaseMutex 方法来释放线程的所有权。
using System;
using System.Threading;
class Example
{
// Create a new Mutex. The creating thread does not own the mutex.
private static Mutex mut = new Mutex();
private const int numIterations = 1;
private const int numThreads = 3;
static void Main()
{
// Create the threads that will use the protected resource.
for(int i = 0; i < numThreads; i++)
{
Thread newThread = new Thread(new ThreadStart(ThreadProc));
newThread.Name = String.Format("Thread{0}", i + 1);
newThread.Start();
}
// The main thread exits, but the application continues to
// run until all foreground threads have exited.
}
private static void ThreadProc()
{
for(int i = 0; i < numIterations; i++)
{
UseResource();
}
}
// This method represents a resource that must be synchronized
// so that only one thread at a time can enter.
private static void UseResource()
{
// Wait until it is safe to enter.
Console.WriteLine("{0} is requesting the mutex",
Thread.CurrentThread.Name);
mut.WaitOne();
Console.WriteLine("{0} has entered the protected area",
Thread.CurrentThread.Name);
// Place code to access non-reentrant resources here.
// Simulate some work.
Thread.Sleep(500);
Console.WriteLine("{0} is leaving the protected area",
Thread.CurrentThread.Name);
// Release the Mutex.
mut.ReleaseMutex();
Console.WriteLine("{0} has released the mutex",
Thread.CurrentThread.Name);
}
}
// The example displays output like the following:
// Thread1 is requesting the mutex
// Thread2 is requesting the mutex
// Thread1 has entered the protected area
// Thread3 is requesting the mutex
// Thread1 is leaving the protected area
// Thread1 has released the mutex
// Thread3 has entered the protected area
// Thread3 is leaving the protected area
// Thread3 has released the mutex
// Thread2 has entered the protected area
// Thread2 is leaving the protected area
// Thread2 has released the mutex
互斥锁是如何实现的?它是基于硬件的吗?它是否有一些等待机制来确保所有线程都知道当前状态是什么?
这是一篇关于差异的好文章:barrgroup.com/Embedded-Systems/How-To/RTOS-Mutex-Semaphore
有关互斥锁的教程可以帮助您弄清楚:stackoverflow.com/questions/4989451/mutex-example-tutorial
互斥锁就像加油站的浴室钥匙,确保一次只能一个人使用浴室,并且在当前居住者用完并归还钥匙之前,其他人不得使用厕所。