![](/img/trans.png)
[英]Does as-if rule prevent compiler reordering of accesses to global/member variables?
[英]Does as-if rule allow this kind of execution reordering
众所周知,编译器或 CPU 可以根据需要重新排序执行,前提是它们遵循 as-if 规则。 例如,如果我们有这样一段代码:
C = A + B;
D = E + F;
编译器或 CPU 可能在C = A + B
之前执行D = E + F
。 我可以理解。
现在让我们谈谈另一个案例。
说我有两个线程a
和b
。 我想在执行时设置一些标记,以便我可以监控a
和b
的整个过程。
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 - 1
、 b - 1
、 b - 2
和a - 2
但在q
中可能有a - 1
、 a - 2
、 b - 1
和b - 2
? 如果可能发生这种情况,我应该如何设计或使用哪种技术来监控多线程进程?
重新排序和多线程是两个不同的东西:
通过多线程,可能的输出是:
"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++ 编译器对程序执行任何更改:
- 对 volatile 对象的访问(读取和写入)严格按照它们出现的表达式的语义进行。 特别是,它们不会针对同一线程上的其他易失性访问重新排序。 (C++11 起)
- 在程序终止时,写入文件的数据与程序执行时完全一样。
- 发送到交互式设备的提示文本将在程序等待输入之前显示。
- 如果支持 ISO C pragma #pragma STDC FENV_ACCESS 并将其设置为 ON,则浮点算术运算符和 function 调用保证观察到对浮点环境(浮点异常和舍入模式)的更改如果按书面执行,除了强制转换和赋值以外的任何浮点表达式的结果可能具有与表达式类型不同的浮点类型的范围和精度(参见 FLT_EVAL_METHOD),尽管有上述规定,任何中间结果浮点表达式可以计算为无限范围和精度(除非#pragma STDC FP_CONTRACT 为OFF)
你的代码(除了可能的// do something
)什么都不做,所以它甚至可以完全删除 2 代码,按下“c - 1”。
但是如果在打印队列内容之后,那么内容应该是上面显示的 6 个之一。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.