Eri*_*c Z 2 c++ multithreading c++11
我正在研究编译器优化(特别是这里的指令重新排序)可能对多线程程序产生的影响.
假设我们有一个读者线程和一个写作者线程.
// Global shared data between threads
bool data;
bool flag = false;
// writer.cpp
void writer()
{
data = true; // (1)
flag = true; // (2)
}
// reader.cpp
void reader()
{
if (flag)
{
count << data;
}
}
Run Code Online (Sandbox Code Playgroud)
可能符合C++ 11标准的编译器重命令指令(1)和(2)?
根据C++"as-if"规则,转换不应该改变程序的可观察行为.显然,在编译编写器时,编译器通常不能确定是否重新排序(1)并且是否(2)会改变程序的可观察行为,因为data并且flag它们都是可能影响另一个线程的可观察行为的全局变量.
但它在此声明可以发生这种重新排序,请参阅编译时的内存排序.
那么我们需要(1)和之间的编译屏障(2)吗?(我很清楚可能的CPU重新排序.这个问题仅适用于编译器重新排序)
他们绝对可以.编译器没有义务考虑对其他线程或硬件的副作用.
如果您使用volatile或同步(并且这两个不可互换),编译器只被强制考虑这个.
标准内存模型称为SC-DRF,或顺序一致数据竞争免费.数据竞争正是您刚刚描述的情景 - 其中一个线程正在观察非同步变量而另一个线程正在变异.这是未定义的行为.实际上,标准明确地赋予编译器自由,假设没有其他线程或硬件正在读取非易失性非同步变量.编译器在此基础上进行优化是绝对合法的.
顺便说一句,这个链接有点废话.他的"修复"并没有解决任何问题.多线程代码的唯一正确修复是使用同步.
| 归档时间: |
|
| 查看次数: |
409 次 |
| 最近记录: |