以下代码是否符合标准? (或者可以使其合规而不进行x
原子或volatile
?)
这类似于之前的一个问题 https://stackoverflow.com/questions/19680757/in-c11-can-stdatomic-be-used-to-transmit-non-atomic-data-between-two-thread,但是我想引用 C++ 标准的相关部分。
我担心的是原子store()
and 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();
}
对于获取/释放,是的,这就足够了。相关引述(来自参考参数 http://en.cppreference.com/w/cpp/language/memory_model——在大多数情况下与标准一样好):
内存模型
当一个表达式的计算写入某个内存位置而另一个计算读取或修改同一内存位置时,这些表达式被称为冲突。具有两个相互冲突的评估的程序会发生数据竞争,除非其中之一
both conflicting evaluations are atomic operations (see std::atomic
)
- 相互矛盾的评价之一发生在之前另一个(参见
std::memory_order
)
std::内存顺序
发布-获取订单
如果线程 A 中的原子存储被标记memory_order_release
并且线程 B 中来自同一变量的原子加载被标记memory_order_acquire
,从线程 A 的角度来看,在原子存储之前发生的所有内存写入(非原子和宽松原子)在线程 B 中都成为可见的副作用,即一旦原子加载完成,线程 B 就能保证看到线程 A 写入内存的所有内容。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)