【问题标题】:Pre/Post indecrement of pointers atomic?指针的前/后增量原子?
【发布时间】:2011-07-12 18:07:10
【问题描述】:

回到过去 68k 的美好时光,由于堆栈指针和其他更通用的地址寄存器之间的相对一般的关系,前后指针递增/递减都或多或少保证是原子的。由于这种行为显然是 68k 人工制品,可能无法在替代平台上获得最有效的实现,因此假设 C 规范没有声明这些操作的“原子性”是否正确。

【问题讨论】:

  • 没有任何 C 规范对 any 操作的原子性做出任何声明。
  • @Nemo:C1x 保证了新原子操作的原子性。
  • 我不认为 C 本身有任何保证,不。 (至少如果指针增量是指 ++ptr 之类的东西,至少不会。)但是,在许多情况下,实际结果确实是原子的。相关讨论见stackoverflow.com/questions/879077/…
  • 也许你会发现这个答案很有帮助stackoverflow.com/questions/879077/…
  • @shelleybutterfly 和 Fedor:这里有很多很棒的信息;感谢您的链接。

标签: c


【解决方案1】:

假设 C 规范没有声明这些操作的“原子性”是否正确。

是的。当前标准(C99 和 C89,IIRC)没有声明原子性。这绝对是特定于平台的,并且可能也取决于编译器。

如果我可以问,为什么这些操作必须是原子的?

【讨论】:

  • 感谢 Rafe 的回答;只是我正在寻找的信息。当我们过去在旧的 68k 系统上检查汇编输出时,由于写入和指针递增的原子性质,像“move.l d1,(a3)+”这样的指令适用于多进程实现。由于我的组装技能在过去十年中有所下降,我想知道“*a3++ = d1”是否有任何保证。
  • @Taliadon 啊,我明白了。好吧,如果您知道您的代码只会在具有某些操作系统和某些编译器的某些体系结构上编译,那么我想您可以检查程序集输出,但我怀疑这比它的价值更麻烦。
  • 大声笑,我认为你是对的;在阅读了论坛上的一些附加信息后,我真的认为我目前的技能不能胜任这项任务。对我来说假设不是这样会更简单。再次感谢您提供信息,非常感谢。
【解决方案2】:

C 标准根本没有原子操作。但是有一些 GCC 内置函数 described here,还有一些在 C++0X stanard 中。而且您始终可以在代码中使用 POSIX 或其他多线程库或内联汇编程序。

【讨论】:

    【解决方案3】:

    不管标准规定了什么,“巨大”指针上的 80x86 指针算术和赋值都不是原子的,但指针增量和赋值很容易在所有“int”所在的平台上由原子读取和原子写入组成32 位或更大的 ,其中指针与“int”大小相同(某些嵌入式平台具有 16 位 int 但 24 位指针)。然而,读-修改-写序列几乎永远不会在任何多处理器架构上形成一个原子单元,除非采取明确的措施使其表现得如此。

    【讨论】:

      【解决方案4】:

      除非明确记录,否则永远无法保证原子性。在当前的 C 标准下,这意味着 no 可移植代码可以保证原子性——原子运算符必须是特定于平台的。

      正如@ninjalj 在他的评论中所说,C1x 将添加原子运算符。

      【讨论】:

        猜你喜欢
        • 2012-06-11
        • 2016-03-15
        • 2015-12-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-16
        • 2010-10-25
        相关资源
        最近更新 更多