我想知道如何才能std::atomic_ref
有效地实现std::mutex
非原子对象(每个对象一个),因为以下属性似乎很难实施:
相对于通过引用同一对象的任何其他atomic_ref施加的原子操作,通过atomic_ref施加到对象的原子操作是原子的。
特别是以下代码:
void set(std::vector<Big> &objs, size_t i, const Big &val) {
std::atomic_ref RefI{objs[i]};
RefI.store(val);
}
似乎很难实现,因为std::atomic_ref
每次都需要以某种方式进行选择std::mutex
(除非这是由相同类型的所有对象共享的大主锁)。
我想念什么吗?还是每个对象都有责任实施std::atomic_ref
,因此要么是原子的要么携带一个std::mutex
?
实现与自身几乎完全相同std::atomic<T>
。这不是一个新问题。
请参阅std :: atomic的锁在哪里?一个典型的执行std::atomic
/std::atomic_ref
锁的静态哈希表,通过地址索引,非无锁的对象。哈希冲突只会导致额外的竞争,而不是正确性问题。(死锁仍然是不可能的;该锁仅由原子函数使用,从不尝试一次占用2个。)
例如,在GCC上,这std::atomic_ref
是调用__atomic_store
对象的另一种方法。(请参阅GCC手册:atomic Builtins)
编译器知道是否T
足够小以致可以无锁。如果没有,它将调用使用该锁的libatomic库函数。
(有趣的事实:这意味着它仅在对象具有足够的对齐方式时才有效atomic<T>
。但是在包括x86在内的许多32位平台上,uint64_t
可能只有4字节对齐方式。atomic_ref
在这样的对象上可以编译并运行,但如果编译器使用32位SSE 8字节加载/存储来实现它。幸运的是alignof(T) == sizeof(T)
,像64位体系结构中的大多数原始类型那样,具有对象的对象没有危险。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句