“mutex”和“原子操作”之间有什么区别吗?

15
我现在正在学习操作系统,对两个概念-互斥锁和原子操作感到困惑。在我看来,它们是相同的,但我的操作系统讲师给我们提出了这样一个问题,
假设一个多处理器操作系统内核跟踪每个用户创建的进程数。该操作系统内核为每个用户维护一个计数器变量,每次为用户创建新进程时增加该计数器变量,并在每次来自该用户的进程终止时减少。此外,该操作系统运行在提供原子获取和增量以及获取和减量指令的处理器上。
操作系统应该使用原子递增和递减指令更新计数器,还是应该在由互斥锁保护的临界区中更新计数器?
这个问题表明互斥锁和原子操作是两个不同的概念。有人能帮我解决这个问题吗?
3个回答

30
一个原子操作是指不能被细分为更小的部分的操作。因此,它永远不会半途而废,所以您可以保证它始终处于一致的状态下。例如,现代硬件实现了原子比较和交换操作。 互斥锁(缩写为互斥)排除其他进程或线程执行相同的代码段(临界区)。基本上,它确保最多只有一个线程执行给定的代码段。互斥锁也称为
在底层,锁必须以某种方式使用硬件实现,并且实现必须利用底层硬件的原子性保证。

大多数复杂的操作都不能变成原子操作,因此您必须使用锁来阻止其他线程在关键部分执行时进行操作,或者您必须仔细设计一个无锁算法,以确保所有关键状态更改操作都可以安全地使用原子操作实现。

这是一个非常深奥的主题,有很多文献涉及到这些话题。我提供的维基百科链接是一个很好的起点,但由于您正在学习操作系统课程,最好向您的教授寻求良好的资源来学习和理解这些内容。


NO. 一个互斥锁本身不能“排除其他进程或线程执行相同的代码段”。 互斥锁有助于程序员防止某些事情发生,但互斥锁本身无法排除任何内容。 如果我们删除一个文件,就可以排除其他进程或线程从中读取。 但是,仅通过创建一个带有相同名称和扩展名“请不要触摸我”的第二个文件(这基本上就是互斥锁所做的事情), 我们几乎排除了“几乎没有人”从中读取。 - ilias iliadis
7
@iliasiliadis: 我认为你在这里过于追求细节。互斥锁排除了正在运行与当前进程和线程相同代码的其他进程或线程执行相同的代码段(关键部分)。是的,没错,_无关_的进程和线程可以自由地与我关键部分相同的外部资源进行交互,但它们并没有 运行 我的关键部分,这是一个重要的区别。 - Daniel Pryden
1
当然,还有单进程(用户空间)互斥锁和跨进程(内核)互斥锁之间的区别;我不想在这个答案中涉及到那个技术细节层面,因为这只是一个高层次的总结,而不是深入的解释。 - Daniel Pryden

10
如果你是一个完全的新手,我的答案可能是一个好的起点。我刚学会这些东西,并且感觉我可以把它们解释清楚。
一般来说,这两个东西都是为了避免你读到一半写的东西时发生不良后果。
互斥锁类似于小企业浴室的钥匙。只有一个人拥有钥匙,所以如果其他人过来,他们可能得等待。但是有以下问题:
- 如果有人拿走了钥匙,则等待的人永远不会停止等待。 - 没有什么可以阻止其他进程制作自己的浴室门。
在代码的上下文中,互斥锁主要是钥匙部分,而人则是进程。
原子意味着无法分成更小的步骤。在自然界中没有CPU时钟 - 所以我们做的一切都可能是更小的步骤 - 但让我们假装...
当你在键盘上打字时,你击打的每个键都是一个原子操作。它一次性完成,你不能同时按下两个键。以下是好处:
- 没有等待:没有同时按下两个键的事实,不是因为一个必须等待。这是因为第一个总是在下一个抵达之前完成。 - 没有冲突:无论你怎样敲打,你永远不会得到两个字符叠加。其中一个总是完全先于另一个发生。
在代码的上下文中,按键与运行单个CPU命令相同。不管队列中有什么其他命令,你正在执行的命令都将在下一个命令发生之前完全完成。
如果可以以原子方式执行某些操作,则您就不必担心冲突。但并非所有事情都适合原子操作。通常,原子操作用于低级操作(例如获取和设置一个基本类型(int,boolean等)。对于任何需要运行大量CPU命令但希望是原子操作的内容,有几个技巧:
- 使用互斥锁。这有点作弊,不是真正的原子操作。但有些事情会这样做并称自己为原子操作。 - 仔细编写代码,使其永远不需要在一个数据上连续进行多个并发指令以保持正确性。这一点深入一些,但有时可以做到。
从这里开始,有很多阅读可以深入了解详细信息,但这应该足以让您建立主题的基础理解。

4

首先阅读 @Daniel 的回答,然后再看我的。

如果您的处理器提供了足够完成任务的原子指令,那么您就不需要使用互斥锁。在您的情况下,fetch-incrementfetch-decrement 应该是原子的,因此您不需要使用互斥锁。

原子操作使用低级别/硬件级别的锁来使一些操作“原子化”:即在一个CPU周期内实际执行的操作。因此,原子操作永远不会使系统处于不一致状态。

编辑

不,原子操作和互斥锁不是同一件事,而是两个用于确保系统状态不变得不一致的相反的东西。对于非原子操作,您使用互斥锁,而对于原子操作,您不使用互斥锁。


1
丹尼尔说:“在底层,锁必须以某种方式使用硬件实现,并且实现必须利用底层硬件的原子性保证。”但你说:“原子操作使用低级别/硬件级别的锁来使某些操作具有原子性。” - Jason Law

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接