【问题标题】:Memory Models and Concurrency [closed]内存模型和并发[关闭]
【发布时间】:2018-08-18 20:37:02
【问题描述】:

我想了解 C/C++ 内存模型,但我在所有文章、博客、youtube 视频中发现“内存模型仅用于并发”..

谁能向我解释一下为什么会这样?

我知道内存模型是一种抽象,它允许程序员使用编程语言来推理底层内存系统(正确吗?)所以一般来说(独立于编程语言)我们是否仍然需要内存模型单线程程序?

谢谢!

【问题讨论】:

  • 欢迎来到 Stack Overflow。请尽快阅读AboutHow to Ask 页面。像这样的问题,尤其是同时标记为cc++ 时,太宽泛了,无法在 SO 上回答。这需要很多解释;已经写了关于这个主题的书。 C 和 C++ 之间存在重大差异,尤其是在实际实现的内容与标准所说的可能由符合标准的实现实现的内容相比方面。
  • @JonathanLeffler 我认为无论语言如何,答案都是一样的。这是一个更根本层面的问题。所以我认为它并不广泛。 OP 可能使用了 C 和 C++ 标签,因为他们希望这些社区能够回答这个问题。
  • 术语内存模型根据上下文以不同的方式使用。我认为 OP 认为是memory addressing model

标签: c++ c memory concurrency memory-model


【解决方案1】:

我了解内存模型是一种抽象,它允许 程序员使用一个推理底层内存系统 编程语言(对吗?)

内存一致性模型是一组规则,允许程序员从访问状态的每个单独代理(核心)的角度推断程序在执行期间的任何时间点的可能状态,如果满足某些条件(例如没有数据竞争)。

我想了解 C/C++ 内存模型,但我在所有的 “只需要内存模型”的文章、博客、YouTube 视频 并发”..

谁能告诉我为什么会这样?

有一些规则可以被视为内存模型的一部分,这些规则也适用于单线程程序的上下文。特别是:

  • 在写入同一位置之后的读取将读取写入的值,而不是旧值。
  • 对同一位置的另一次写入之后的写入将覆盖先前写入的值。
  • 读取同一位置后的写入只会在读取完成后修改该位置。

但是,这些规则被认为是如此基本和直观,以至于不值得在每个内存模型中都说明它们。在 VLIW 架构的情况下,编译器会自动遵循这些规则。在传统架构的情况下,编译器(根据源代码中语句的顺序)和处理器都遵循这些规则(根据指令流的顺序)。所以基本上说明它们是多余的。除此之外,单线程程序没有其他有用的规则。

【讨论】:

    【解决方案2】:

    内存模型不适用于单线程代码的原因是在ST代码中你执行一个又一个语句并且没有混淆的可能性。在多线程代码中,对象的值可能会在不警告当前线程的情况下更改。内存模型概念可让您确保在所有其他线程完成更新值之后执行特定语句,或者确保在任何其他线程读取对象值之前执行特定语句。

    【讨论】:

      【解决方案3】:

      这是来自https://en.wikipedia.org/wiki/Memory_model_(programming)的引用

      内存模型允许编译器执行许多重要的优化。编译器优化,例如程序中的循环融合移动语句,这可能会影响潜在共享变量的读写操作的顺序。读取和写入顺序的变化可能会导致竞争条件。

      编译器可以改变变量的读写顺序,并且仍然保证代码片段会像读/写顺序一样运行。但是如果涉及到多线程,这可能会导致问题,因为读取/写入变量,而不是按代码顺序,可能会导致多线程相关的问题。

      检查以下由 2 个线程执行的代码,它们都使用相同的变量 init 和 value:

      static int init = 0;
      static int value = 0;
      
      thread_a:
      while( !init )
          Sleep( 100 );
          if ( value == 100 )
              do something ...
      
      thread_b:
          value = 100;
          init = 1;
      

      编译器可能会以不同的顺序(或并行)运行 thread_b 的代码,导致 init 在值设置为 100 之前设置为 1。当使用单线程时,这没有意义,但是,当有多个线程时检查这些变量,这可能会导致问题。而这里的内存模型来解决这个问题。

      【讨论】:

        【解决方案4】:

        一般所说的内存模型是指不同的执行线程访问对象的交互。从这个意义上说,它完全与并发相关。这与记忆无关。

        还有一个重要的方面被称为对象模型Stan Lippman’s book 是一个很好的学习资源(它有点过时,但主要是相关的)。对象模型也没有真正讨论如何访问内存。

        最接近一般如何访问内存的描述是 Ulrich Drepper 的 What Every Programmer Should Know About Memory_。这篇文章是关于内存的一般视图,独立于编程语言。当然,根据对象模型的不同,不同的编程语言可能会隐藏与内存的直接交互。

        【讨论】:

          猜你喜欢
          • 2018-03-26
          • 1970-01-01
          • 2011-02-04
          • 1970-01-01
          • 2013-06-05
          • 1970-01-01
          • 2010-09-18
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多