C++ 记忆屏障示波器

C++ 记忆屏障示波器,c++,c++11,c++14,C++,C++11,C++14,我不确定std::memory\u order\u release或std::memory\u order\u acquire内存屏障的范围是什么。下面是一个例子。我调整了代码以表达我的观点: #include <atomic> #include <cassert> #include <string> #include <thread> #include <iostream> std::atomic<std::string*&g

我不确定
std::memory\u order\u release
std::memory\u order\u acquire
内存屏障的范围是什么。下面是一个例子。我调整了代码以表达我的观点:

#include <atomic>
#include <cassert>
#include <string>
#include <thread>
#include <iostream>

std::atomic<std::string*> ptr;

void producer()
{
  std::string* p  = new std::string("Hello");

  ptr.store(p, std::memory_order_release);
}

bool acquire(std::string* p2)
{
  while (!(p2 = ptr.load(std::memory_order_acquire)));

  return p2 != nullptr;
}

void consumer()
{
  std::string* p2 {nullptr};

  // while (!(p2 = ptr.load(std::memory_order_acquire))); // prints "makes sense"
  assert(acquire(p2)); // prints "what's going on?"

  if (p2 == nullptr)
  {
    std::cout << "what's going on?" << std::endl;
  }
  else
  { 
    std::cout << "makes sense" << std::endl;
  }
}

int main()
{
  std::thread t1(producer);
  std::thread t2(consumer);
  t1.join(); t2.join();
}
#包括
#包括
#包括
#包括
#包括
std::原子ptr;
无效生产者()
{
std::string*p=newstd::string(“Hello”);
ptr.存储(p,std::内存\订单\发布);
}
bool获取(标准::字符串*p2)
{
而(!(p2=ptr.load(std::memory\u order\u acquire));
返回p2!=nullptr;
}
无效消费者()
{
std::string*p2{nullptr};
//而(!(p2=ptr.load(std::memory_order_acquire));//打印“有意义”
assert(acquire(p2));//打印“发生了什么?”
如果(p2==nullptr)
{
标准::cout
  • acquire()
    函数中使用的
    std::memory\u order\u acquire
    仅用于acquire()的范围
  • 否。它适用于线程,不受任何函数边界的约束

  • 怎么可能打印“发生了什么事?”
  • 因为您正在修改指针的副本。更改:

    bool acquire(std::string* p2)
    
    致:


    使函数引用与传递给它的指针相同。

    与内存语义无关。在一种情况下,您直接分配给正在打印的指针,而在另一种情况下,您没有。您有两个不同的
    std::string*p2
    。它们不是同一个变量!您正在分配给one,然后检查另一个是否仍然为空。@Drew Dorman谢谢!我犯了一个愚蠢的错误。我将再次编辑该问题。@AdvSphere我已经发布了答案。如果您有新的、不同的问题,请发布一个新问题。@Drew Dorman会的!再次感谢!
    bool acquire(std::string*& p2)