微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

as-if 规则是否允许这种执行重新排序

如何解决as-if 规则是否允许这种执行重新排序

正如我们所知,编译器或 cpu 可能会根据需要重新排序执行,前提是它们遵循 as-if 规则。例如,如果我们有这样一段代码

C = A + B;
D = E + F;

编译器或 cpu 可能会在 D = E + F 之前执行 C = A + B。我能理解。

现在我们来谈谈另一个案例。

我有两个线程ab。我想在执行时设置一些标记,以便我可以监控ab的整个过程。

queue q; // thread safe

void thread_a()
{
    // do something
    q.push("a - 1");
    // do something
    q.push("a - 2");
}

void thread_b()
{
    // do something
    q.push("b - 1");
    // do something
    q.push("b - 2");
}

我的问题是:既然我们有 as-if 规则并且执行顺序可能会重新排序,那么是否意味着 q 中的消息不可靠?这意味着真正的执行顺序是 a - 1b - 1b - 2a - 2 但在 q 中可能有 a - 1、{{1 }}、a - 2b - 1?如果发生这种情况,我应该如何设计或使用哪种技术来监控多线程进程?

解决方法

重新排序和多线程是两件事:

通过多线程,可能的输出是:

  • "a - 1""a - 2""b - 1""b - 2"
  • "a - 1""b - 1""a - 2""b - 2"
  • "a - 1""b - 1""b - 2""a - 2"
  • "b - 1""b - 2""a - 1""a - 2"
  • "b - 1""a - 1""b - 2""a - 2"
  • "b - 1""a - 1""a - 2""b - 2"

您只需保证“a - 1”在“a - 2”之前,并且“b - 1”在“b - 2”之前。 (与重新排序无关)

使用 as-if 规则重新排序只是一种优化。

as_if 声明:

只要满足以下条件,C++ 编译器就可以对程序进行任何更改:

  1. 对 volatile 对象的访问(读取和写入)严格按照它们出现的表达式的语义进行。特别是,它们不会相对于同一线程上的其他易失性访问重新排序。 (C++11 起)
  2. 在程序终止时,写入文件的数据就如同程序按照写入的方式执行一样。
  3. 发送到交互式设备的提示文本将在程序等待输入之前显示。
  4. 如果支持 ISO C pragma #pragma STDC FENV_ACCESS 并将其设置为 ON,则浮点算术运算符和函数调用就像按编写的那样执行,除了 除强制转换和赋值之外的任何浮点表达式的结果可能具有与表达式类型不同的浮点类型的范围和精度(请参阅 FLT_EVAL_METHOD) 尽管如此,任何浮点表达式的中间结果都可以计算为无限范围和精度(除非#pragma STDC FP_CONTRACT 为 OFF)

你的代码(除了可能的 // do something)什么都不做,所以它甚至可以完全删除 2 代码,按下“c - 1”。

但是如果在打印队列内容之后,那么内容应该是上面显示的 6 个之一。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。