【问题标题】:What happens in two execution units, if two threads within the same process managed by the OS accessing in the same time to the same virtual address?如果操作系统管理的同一进程中的两个线程同时访问同一虚拟地址,那么在两个执行单元中会发生什么?
【发布时间】:2020-02-16 18:46:01
【问题描述】:

在Core2 Duo等具有两个执行单元的计算系统中,如果同一进程中由操作系统(内核级线程)管理的两个线程在运行时访问同一个虚拟内存地址会怎样?

嗨,我想了解用户级线程和内核级线程之间的区别以及访问虚拟 memory 地址?还是物理内存地址?... 我不知道这些程序是否不会崩溃并且两者都会给出预期的结果,或者这些程序是否不会崩溃但都会给出意想不到的结果,或者这些程序可能会崩溃。

什么应该指导我?

谢谢。

【问题讨论】:

  • 除非他们使用locking,否则行为将是未定义的,这意味着在不同的系统上你会看到不同的东西——崩溃、部分或不一致的内存更改等。
  • 首先,在千兆赫频率和纳米距离的背景下准确定义“同一时间”。
  • @AndrewHenle 我认为这里不需要对“同一时间”进行任何特殊定义。
  • @MaximEgorushkin 鉴于任何答案都必须依赖于底层硬件的设计方式,如果不解决“同一时间”的真正含义,就无法描述“发生了什么”。两个不同的 CPU 试图访问同一个 RAM?同一个 CPU 上的两个线程访问同一个缓存?当信号以千兆赫频率在纳米距离上通过数百万个晶体管运行时,信号“同时”发生的想法几乎没有意义。这个问题隐含地假设答案是可能的,但未能解释任何关键的潜在细节。
  • @AndrewHenle IMO,你无缘无故地把事情复杂化了。两个线程可以大致同时产生缺页中断,并争夺对内核数据结构的访问。这种争用通过使用同步原语以通常的方式解决。

标签: multithreading parallel-processing operating-system


【解决方案1】:

从我从您的问题中可以看出,您混合了不同的概念,即:多个执行单元和竞争条件、虚拟内存和用户级别与内核级别线程

在Core2 Duo等具有两个执行单元的计算系统中,如果同一进程中的两个线程在运行时由操作系统管理(内核级线程)访问同一个虚拟内存,会发生什么情况

这通常总是如此,n 核心/处理器无关紧要。这是多线程的一个基本概念。所以What happens 与what will happen when multiple threads access a shared resource 相同。通常的竞争条件总是需要由开发人员解决。

现在不要将Virtual memory 与此混合。用户/内核级线程都只会在虚拟寻址模式下访问内存地址。发生这种情况是因为一旦在保护模式下启用虚拟内存,处理器就会隐式地将虚拟地址转换为物理地址(使用 OS 设置的页表/等)。

【讨论】:

    【解决方案2】:

    在Core2 Duo等具有两个执行单元的计算系统中,如果同一进程中的两个线程在运行时由操作系统管理(内核级线程)访问同一个虚拟内存,会发生什么?

    发生以下两种情况之一:

    1. 如果在执行单元中运行的软件的作者遵循平台对此类访问的规则,他们将获得平台为此类访问指定的任何行为。

    2. 如果在执行单元中运行的软件的作者没有遵循平台对此类访问的规则,结果通常是不可预测或未定义的。

    一个典型的平台规则可能是一个对象不能在一个线程或执行单元中被访问,而另一个线程或执行单元正在或可能正在修改它。典型的现代平台在同时读取方面没有问题。

    【讨论】:

      【解决方案3】:

      有两种情况:

      1. 内存页框已被映射并具有兼容的访问权限。在这种情况下,两个线程都访问内存。
      2. 内存页框未映射或访问权限不同。在这种情况下,访问线程生成一个硬件中断,内核通过映射页面来处理该中断,或者如果页面无法映射,则为线程生成信号SIGSEGV。当另一个线程在映射时访问同一个页框时,该线程会阻塞内核中的同步原语,直到映射操作完成(在 Linux 中是 struct mm_struct 的成员 rw_semaphore mmap_sem)。换句话说,操作系统内核保护其数据结构免受竞争条件的影响。

      【讨论】:

        【解决方案4】:

        “在并发内存访问期间会发生什么”的简短回答是,这很复杂。

        关于这个主题的最规范的报告可能是Memory Consistency Models for Shared-Memory Multiprocessors, by Kourosh Gharachorloo。介绍的第一段现在可能看起来有点过时,但他提供了足够的背景信息,使报告对非专家来说非常易读,并且从那时起实际上没有任何根本性的变化。

        Core 2 Duo 遵循 处理器一致性 模型(与所有其他 x86 CPU 一样),因此如果没有任何显式同步,所有处理器将有效地同意写入任何给定内存位置的顺序,但是当从不同的位置读取,他们可以以不同的顺序观察写入。

        Core2 Duo 通过MESI protocol 实现缓存一致性。

        请记住,由于 x86 允许非对齐访问,如果碰巧跨越了缓存行边界,那么在单个指令中看起来像单个内存访问实际上可能是对不同位置的两个内存访问 .如果您使用高级语言(高于汇编语言)进行编程,该语言可能会将其自己的语义强加于并发内存访问(通常会这样做)。

        【讨论】:

          【解决方案5】:

          What happens... 的问题涉及不同的抽象级别(用户空间到硬件)。

          其实What happens是在处理硬件级别:

          有两个并发(基本上发生在同一个机器周期)访问同一个物理内存地址。

          出现以下 3 种可能性: (给定一个内存地址X,内容为C(X)为x0。)

          a) 两次读取 这将有一个确定性的结果:两者都将观察x0 作为值。

          b) 一读一写(值:x1) 读者可能会观察到x0 或x1,这取决于访问的顺序(见下文)。

          c) 两次写入(值:x1,x2) 最终内容 C(X) 可能会以 x1 或 x2 结尾,具体取决于排序(见下文)

          在情况 b) 和 c) 中,观察者可能会得到非确定性行为的印象。然而,底层行为实际上仍然是确定性的。

          这些并发 (at the same time) 访问的实际结果取决于硬件的详细信息。主要是:

          • 公交分配策略
          • 缓存一致性策略

          实际使用的操作系统不会对此行为产生重大影响。 该问题已经需要在(大级别)执行单元(问题中的线程)之间共享内存,但是使用共享内存段的进程(默认为单独的内存)将表现相似。 任何同步机制(锁、信号量)的使用都只会阻止并发访问的发生,从而消除并发访问的发生。

          您可能会想到原子操作(通常在物理内存上执行独占的读取-修改-写入循环),因为这将允许正在执行的执行单元“知道”是否确实发生了任何“其他”操作等导致更确定的操作顺序。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-06-10
            • 2019-11-03
            • 1970-01-01
            • 1970-01-01
            • 2013-10-20
            • 2014-03-18
            相关资源
            最近更新 更多