C++ 可以使用std::原子内存屏障在线程之间传输非原子数据吗?

C++ 可以使用std::原子内存屏障在线程之间传输非原子数据吗?,c++,c++11,language-lawyer,memory-model,C++,C++11,Language Lawyer,Memory Model,是否符合以下规范标准?(或者可以在不使x原子化或易失性的情况下使其符合要求吗?) 这是相似的,但是我想引用C++标准的相关部分。 我担心的是,原子store()和load()没有为非原子变量(x在下面的示例中)提供足够的编译器屏障,以获得正确的释放和语义 < >我的目标是实现无锁的原语,例如队列,它可以在线程之间传递指针到常规C++数据结构。 #include <atomic> #include <chrono> #include <iostream> #in

是否符合以下规范标准?(或者可以在不使
x
原子化或
易失性的情况下使其符合要求吗?)

<>这是相似的,但是我想引用C++标准的相关部分。 我担心的是,原子
store()
load()
没有为非原子变量(
x
在下面的示例中)提供足够的编译器屏障,以获得正确的释放和语义

< >我的目标是实现无锁的原语,例如队列,它可以在线程之间传递指针到常规C++数据结构。
#include <atomic>
#include <chrono>
#include <iostream>
#include <thread>

int x; // regular variable, could be a complex data structure

std::atomic<int> flag { 0 };

void writer_thread() {
    x = 42;
    // release value x to reader thread
    flag.store(1, std::memory_order_release);
}

bool poll() {
    return (flag.load(std::memory_order_acquire) == 1);
}

int main() {
    x = 0;

    std::thread t(writer_thread);

    // "reader thread" ...  
    // sleep-wait is just for the test.
    // production code calls poll() at specific points

    while (!poll())
      std::this_thread::sleep_for(std::chrono::milliseconds(50));

    std::cout << x << std::endl;

    t.join();
}
#包括
#包括
#包括
#包括
int x;//正则变量,可能是一个复杂的数据结构
std::原子标志{0};
void writer_thread(){
x=42;
//将值x释放到读卡器线程
存储标志(1,标准::内存\顺序\释放);
}
布尔民意测验{
返回(flag.load(std::memory\u order\u acquire)==1);
}
int main(){
x=0;
std::线程t(写入线程);
//“读者线程”。。。
//睡眠等待只是为了测试。
//生产代码在特定点调用poll()
而(!poll())
std::this_线程::sleep_for(std::chrono::毫秒(50));

std::cout对于acquire/release,是的,这就足够了。相关引用(在大多数情况下与标准一样好):

记忆模型 当一个表达式的求值写入内存位置,而另一个求值读取或修改同一内存位置时,这些表达式被称为冲突。具有两个冲突求值的程序具有数据竞争,除非

  • 两个冲突的计算都是原子操作(请参见
    std::atomic
  • 一个冲突的求值发生在另一个求值之前(请参见
    std::memory\u order
std::内存顺序 发布获取命令 如果线程A中的原子存储被标记为
内存\u顺序\u释放
,线程B中来自同一变量的原子负载被标记为
内存\u顺序\u获取
,则所有内存写入(非原子和松弛原子)从线程A的角度来看,这发生在原子存储在线程B中变成可见的副作用之前,也就是说,一旦原子加载完成,线程B就可以保证看到线程A写入内存的所有内容。


我看这里没有任何问题。你能更详细地谈谈你认为不安全的地方吗?