在复制构造函数中复制原子的非锁定方式
Nonlocking Way to Copy Atomics in Copy Constructor
我正在为需要将两个 std::atomic<T>
成员复制到新对象中的数据结构编写复制构造函数。虽然在我的用例中该过程不一定必须是原子的,但我更愿意尽可能拥有最正确的解决方案。
我知道 std::atomic<T>
明确删除了复制构造函数,以强制用户使用原子接口。
atomic(const atomic&) = delete;
我现在正在做的事情是这样的:
SomeObject(const SomeObject& other):
_atomic1(other._atomic1.load()),
_atomic2(other._atomic2.load()) {
...
}
我不相信这个操作是原子的,我也不知道有什么方法可以做到这一点(没有锁)。
有没有办法自动复制这些值(没有锁)?
唯一的方法是制作一个包含两个 T
的简单可复制结构 S
并使用 std::atomic<S>
.
请注意,这仅在您从一开始就使用此 S
时才有效 - 无法在没有锁的情况下以原子方式加载两个单独的原子。
所以代替:
struct SomeObject {
SomeObject(const SomeObject& other) : i(other.i.load()), j(other.j.load()) { }
std::atomic<int> i, j;
};
这样做:
struct SomeObject {
SomeObject(const SomeObject& other) : data(other.data.load()) { }
struct Data { int i, j; };
std::atomic<Data> data;
};
请注意,这可能(可能)仍然在内部使用锁。使用 is_lock_free
检查是否存在。
我正在为需要将两个 std::atomic<T>
成员复制到新对象中的数据结构编写复制构造函数。虽然在我的用例中该过程不一定必须是原子的,但我更愿意尽可能拥有最正确的解决方案。
我知道 std::atomic<T>
明确删除了复制构造函数,以强制用户使用原子接口。
atomic(const atomic&) = delete;
我现在正在做的事情是这样的:
SomeObject(const SomeObject& other):
_atomic1(other._atomic1.load()),
_atomic2(other._atomic2.load()) {
...
}
我不相信这个操作是原子的,我也不知道有什么方法可以做到这一点(没有锁)。
有没有办法自动复制这些值(没有锁)?
唯一的方法是制作一个包含两个 T
的简单可复制结构 S
并使用 std::atomic<S>
.
请注意,这仅在您从一开始就使用此 S
时才有效 - 无法在没有锁的情况下以原子方式加载两个单独的原子。
所以代替:
struct SomeObject {
SomeObject(const SomeObject& other) : i(other.i.load()), j(other.j.load()) { }
std::atomic<int> i, j;
};
这样做:
struct SomeObject {
SomeObject(const SomeObject& other) : data(other.data.load()) { }
struct Data { int i, j; };
std::atomic<Data> data;
};
请注意,这可能(可能)仍然在内部使用锁。使用 is_lock_free
检查是否存在。