"互斥"和"原子操作"之间有什么区别吗?

Jay*_*Jay 4 multithreading operating-system

我现在正在学习操作系统,我对这两个概念感到困惑 - 互斥原子操作.在我的理解中,它们是相同的,但我的操作系统老师给了我们这样一个问题,

假设多处理器操作系统内核跟踪每个用户创建的进程数.此操作系统内核为每个用户维护一个计数器变量,每次为用户创建新进程时它都会递增,并在每次从该用户终止进程时递减.此外,该操作系统在提供原子提取和递增以及提取和递减指令的处理器上运行.操作系统是否应使用原子递增和递减指令更新计数器,还是应更新受互斥锁保护的临界区中的计数器?

这个问题表明互斥和原子操作是两回事.任何人都可以帮我吗?

Dan*_*den 11

一个原子操作是一个不能被细分成更小的部分.因此,它永远不会中途完成,因此您可以保证始终以一致的状态观察它.例如,现代硬件实现原子比较和交换操作.

互斥(以下简称互斥)排除从执行相同的代码部分(另一进程或线程临界区).基本上,它确保最多一个线程正在执行给定的代码段.互斥锁也称为.

在引擎盖下,锁必须以某种方式使用硬件实现,并且实现必须利用底层硬件的原子性保证.

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

这是一个非常深刻的主题,并且有大量关于所有这些主题的文献.我给出的维基百科链接是一个很好的起点,但由于你现在正在操作系统上课,所以最好让你的教授为学习和理解这些东西提供良好的资源.

  • @iliasiliadis:我认为你在这里过于迂腐了。互斥锁会排除与当前进程和线程运行相同代码的其他进程或线程执行同一代码段(临界区)。是的,确实如此,_不相关的_进程和线程可以自由地与与我的临界区相同的外部资源进行交互——但它们并不_运行_我的临界区,这是重要的区别。 (5认同)

Sep*_*eed 10

如果你是个菜鸟,我的回答可能是一个很好的起点。我刚刚了解了这些是如何工作的,并且感觉我处于一个很好的位置来转发。

一般来说,这两种方法都是为了避免当你读到一半的东西时发生不好的事情。


互斥体

互斥体就像小型企业浴室的钥匙。只有一个人拥有钥匙,因此如果其他人出现,他们可能需要等待。这是摩擦点:

  • 如果有人拿着钥匙走了,那么等待的人就永远不会停止等待。
  • 没有什么可以阻止其他进程为自己打开通往浴室的门。

在代码上下文中,互斥锁主要是关键部分,而人是一个进程。


原子

原子意味着不能分成更小的步骤。在自然世界中没有 CPU 时钟——所以我们所做的一切都可以是更小的步骤——但是让我们假设......

当您在键盘上打字时,您按下的每个键都是原子操作。它是同时发生的,你不能同时按下两个键。这是这样做的好处:

  • 无需等待:没有同时按下两个键这一事实并不意味着必须等待。这是因为一个总是在下一个到达时完成。
  • 没有碰撞:无论你如何锤击,你永远不会让两个角色重叠。一个总是完全先于另一个发生。

举个反例,如果您尝试同时键入两个单词,则这不是原子的。这些字母会混淆。

在代码上下文中,击键与运行单个 CPU 命令相同。无论队列中有什么其他命令,您正在执行的命令都会在下一个命令发生之前完全完成。

如果你可以原子地做某事,那么你就不必担心碰撞。但在这些范围内并非一切都是可行的。一般来说,原子用于非常低级的操作——比如获取和设置一个原语(int、boolean 等)。对于任何要运行一堆 CPU 命令但想要原子化的东西,有几个技巧:

  1. 使用互斥体。有点作弊,不是真正的原子。但有些东西做到了这一点并称自己为原子的。
  2. 仔细编写代码,使其永远不需要对一行中的一条数据执行多个并发指令才能保持正确。这个有点深入,但有时是可以做到的。

从这里开始,有大量的阅读内容可以深入了解本质细节,但这应该足以让您对这个主题有一个基础的理解。