Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ “仿佛”规则是否阻止编译器对全局/成员变量的访问进行重新排序?_C++_Multithreading_C++11 - Fatal编程技术网

C++ “仿佛”规则是否阻止编译器对全局/成员变量的访问进行重新排序?

C++ “仿佛”规则是否阻止编译器对全局/成员变量的访问进行重新排序?,c++,multithreading,c++11,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)

我正在研究编译器优化(特别是这里的指令重新排序)对多线程程序的影响

假设我们有一个读线程和一个写线程

// 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;
    }
}
//线程之间的全局共享数据
布尔数据;
布尔标志=假;
//writer.cpp
空写器()
{
数据=真;//(1)
flag=true;//(2)
}
//reader.cpp
无效读取器()
{
国际单项体育联合会(旗)
{

绝对可以。编译器没有义务考虑其他线程或硬件的副作用。

<>编译器只有在使用<代码>易失性> /代码>或同步(这两个是不可交换的)时才会考虑这一点。

标准内存模型称为SC-DRF,或顺序一致性无数据竞争。数据竞争正是您刚才描述的场景——一个线程正在观察非同步变量,而另一个线程正在对其进行变异。这是未定义的行为。实际上,该标准显式地为编译器提供了如下自由:假设没有其他线程或硬件正在读取非易失性非同步变量。编译器在这个基础上进行优化是绝对合法的


顺便说一句,那个链接有点垃圾。他的“修复”对于多线程代码来说,唯一正确的解决方法是使用同步。

< p>您已经在COMP.Lang.c++上提出了这个问题。一周半以前,您已经给出了一个完整的解释,说明C++ 11对单个线程中的排序要求和线程间同步的“之前发生”关系,如下所示:


回答的哪一部分您不明白,我们可以再试一次?

这是关于内存访问的重新排序(指令重新排序),还是关于内存中变量的重新排序(更改内存布局)?这是关于指令重新排序的。请参阅@EricZ:相应地修复了标题。我认为指令重新排序从上下文来看是显而易见的。顺便问一下,“内存中的变量重新排序”是如何关联的?我很清楚可能的CPU重新排序。这个问题只涉及编译器重新排序“-所以你不在乎你的程序是否因为cpu重新排序而中断,但如果编译器重新排序,你会在意吗?这个链接没有问题。他只关注编译时的重新排序,忽略了其他部分。他没有说代码解决了所有同步问题,他在其他帖子中也提到了。这意味着什么“仿佛”规则只适用于单线程?我感到困惑的主要原因是它提到的是“程序”而不是“单线程”,我认为“单线程”在C++11中是多线程的,这意味着“可观察的行为”包括来自多线程的行为。@EricZ“仿佛”规则只适用于正确的程序。一个包含数据竞争(“数据竞争”)的程序“有一个特定的定义,包括您可能认为不属于数据竞争的内容)不是一个正确的程序,因此实现可能只对不包含数据竞争的程序有效。@Eric很简单-给定程序的行为是未定义的,因为我们同时进行了非同步读写。因此,无论标准中说什么,都是无效的。@hvd Right,它是al关于未定义的行为。魔鬼再次出现在细节中。谢谢;)+1:谢谢你提醒我那篇文章,这真的结束了我的困惑;)