std::atomic 在哪里隐藏它的锁?
在多元素数据结构中,标准原子类型可能并不总是锁 -自由的。这是由于 CPU 在没有锁的帮助下无法处理此类数据。为了说明这一点,请考虑以下示例:
#include <iostream> #include <atomic> struct foo { double a; double b; }; std::atomic<foo> var; int main() { std::cout << var.is_lock_free() << std::endl; std::cout << sizeof(foo) << std::endl; std::cout << sizeof(var) << std::endl; }
Linux/gcc 的输出显示以下内容:
0 16 16
假设原子类型和 foo 结构占用相同的空间量,锁似乎不太可能存储在原子中。但这个难题背后的真相究竟是什么?
多个实例的锁定位置和含义
常规方法涉及使用互斥锁(或自旋锁)键控的哈希表到原子对象的地址。此哈希函数倾向于将地址的最低位作为大小为 2^n 的数组的索引。
否则,LLVM std::atomic 实现会合并较高的地址位以防止自动别名。这确保了由 2 的有效幂分隔的对象不会映射到同一个锁。
重要的是,原子对象仅在不同进程之间共享内存时以无锁方式操作,其中每个进程都配备具有自己的锁哈希表。
哈希表内的冲突可能需要小心。虽然这不会造成正确性问题,但它可能会因促进多个线程之间的争用而损害性能。然而,这种情况相对较少发生,因为无锁原子对象通常在相关平台上受到青睐。
关于死锁,请放心,这不是一个问题,因为 std::atomic 函数不会获取锁同时作用于多个物体。因此,负责获取锁的库代码在持有现有锁的同时绝不会尝试获取额外的锁。
以上是`std::atomic` 是否使用隐藏锁,如果是,它位于哪里?的详细内容。更多信息请关注PHP中文网其他相关文章!