【发布时间】:2020-08-31 14:21:05
【问题描述】:
我了解到线程之间进行通信的一种方法是共享一些原子数据结构。例如:
struct Point {
int const x, y;
};
std::atomic<Point> some_point_in_shared_memory{Point{0, 0}};
尽管Point::operator=(Point const &)被删除,但似乎有no problem调用std::atomic<Point>的赋值运算符如下:
some_point_in_shared_memory = Point{1, 2};
这个操作如何实现?
我可能想到的一个解决方案是使用placement new 在旧对象之上构造一个新对象,但显然是it is not exception safe。还是因为Point 可以轻松复制所以没关系?
【问题讨论】:
-
您能否详细说明“似乎没有问题”?你的代码编译了吗?如果是这样,您的标准库有一个错误,因为
std::atomic<T>要求T可以轻松复制 -
gcc 和 clang 接受这个。 MSVC 和 ICC 没有。
-
@alterigel 见this。还将链接编辑为没问题。此外,
Point可以轻松复制。 -
你在哪里删除
Point::operator=(Point const &)?您将Point声明为普通结构,因此它看起来不像minimal reproducible example。此外,您的标题仍然显示“不可变”。真的是你的意思吗? -
此外,在启用优化的情况下进行编译,以将 asm 输出简化为预期的 qword seq-cst 存储,使用
xchg实现其隐含的lock行为。 godbolt.org/z/sdTEv9
标签: c++ thread-safety stdatomic exception-safety