Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.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++中,MexyYORADORION在代码中不按预期的方式工作_C++_C++11_Concurrency_Atomic - Fatal编程技术网

在C++中,MexyYORADORION在代码中不按预期的方式工作

在C++中,MexyYORADORION在代码中不按预期的方式工作,c++,c++11,concurrency,atomic,C++,C++11,Concurrency,Atomic,在问这个问题之前,我试着将我的VM核心设置为1以上,我将其设置为2,根据的建议,这个解决方案对作者有效,但对我无效 在操作中的C++并发性给出了清单5.5中的例子: #include <atomic> #include <thread> #include <assert.h> std::atomic<bool> x,y; std::atomic<int> z; void write_x_then_y() { x.store(tr

在问这个问题之前,我试着将我的VM核心设置为1以上,我将其设置为2,根据的建议,这个解决方案对作者有效,但对我无效

在操作中的C++并发性给出了清单5.5中的例子:

#include <atomic>
#include <thread>
#include <assert.h>

std::atomic<bool> x,y;
std::atomic<int> z;

void write_x_then_y()
{
  x.store(true,std::memory_order_relaxed);  // 1
  y.store(true,std::memory_order_relaxed);  // 2
}
void read_y_then_x()
{
  while(!y.load(std::memory_order_relaxed));  // 3
  if(x.load(std::memory_order_relaxed))  // 4
    ++z;
}
int main()
{
    for(int i = 0; i < 1000; i++){
      // this loop is addeed by me in order to try 1000 times to see whether the assertion will fail
      x=false;
      y=false;
      z=0;
      std::thread a(write_x_then_y);
      std::thread b(read_y_then_x);
      a.join();
      b.join();
      assert(z.load()!=0);  // 5
    }
}
书上说断言assertz.load=0可能会失败。然而,在测试时,我不能让这个断言失败

我使用VMWare下的64位uBuntuUntuunder、g++-g-o test-std=c++17 test.cpp-lpthread测试了该程序,并在gcc 5.4.0和gcc 7.2.0下进行了测试

我还使用64位Windows 10not在虚拟机Visual studio 2015中测试了该程序


同时,通过搜索互联网,我看到一些人说这是因为x86体系结构,但是,我记得在x86中,旧商店可能会将负载重新排序到不同的位置,因此我认为可能有一个订单2-3-4-1会使此断言失败。

这本书是正确的,断言可能会失败,只是不像你想象的那样在x86上

明确地说,明确保证不会发生任何意外。它本身并不能保证没有

std::memory_order_released是所有内存顺序中最松散的。这是一切的底线。在实践中,它围绕着变量展开

atomic<bool> x, y;
x.store(true,std::memory_order_relaxed);
y.store(true,std::memory_order_relaxed);

// is similar to...
volatile bool x, y;
x = true;
asm volatile("" ::: "memory");  // Tells compiler to stop optimizing here,
                                // but issues no instructions
y = true;

也就是说,如果y在//3处被确定为真,那么//2之前发生的事情保证在//3之后可见。

可能会失败。不保证失败。1,2不会在x86上重新排序,除非编译器重新排序,而且它们通常不会这样做。@Ivan那么如果没有重新排序,那么在什么情况下断言会失败?我猜故障可能与CPU的缓存线有关?在您的示例中,它不能,除非编译器决定重新排序这些存储。当有两个以上的cpu工作时,您可能会看到重新排序:第一个cpu设置x,第二个cpu设置y,第三个cpu首先观察x的变化,第四个cpu首先观察y的变化。有一个例子在:下节顺序一致排序
// On x86, effectively
void write_x_then_y()
{
    x.store(true,std::memory_order_release);  // 1
    y.store(true,std::memory_order_release);  // 2
}
void read_y_then_x()
{
    while(!y.load(std::memory_order_acquire));  // 3
    if(x.load(std::memory_order_acquire))  // 4
        ++z;
}