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写入内存的所有内容。
我看这里没有任何问题。你能更详细地谈谈你认为不安全的地方吗?