当前位置: 首页 > 知识库问答 >
问题:

为什么std::atomic(原子):\u lock\u free()不像constexpr那样是静态的?

漆雕深
2023-03-14

谁能告诉我是否是原子的

为什么它没有像C 17一样设计呢?首先,它总是\u lock\u free吗?

共有3个答案

何哲
2023-03-14

我已经在我的Windows PC上安装了Visual Studio 2019,这个devenv还有一个ARMv8编译器。ARMv8允许未对齐的访问,但必须对齐比较和交换、锁定的添加等。此外,使用ldp或stp(32位寄存器的加载对或存储对)的纯加载/纯存储仅在它们自然对齐时保证是原子的。

所以我编写了一个小程序来检查任意原子指针的\u lock\u free()返回值。下面是代码:

#include <atomic>
#include <cstddef>

using namespace std;

bool isLockFreeAtomic( atomic<uint64_t> *a64 )
{
    return a64->is_lock_free();
}

这是isLockFree原子的拆解

|?isLockFreeAtomic@@YA_NPAU?$atomic@_K@std@@@Z| PROC
    movs        r0,#1
    bx          lr
ENDP

这只是返回true,又名1

此实现选择使用对齐(原子

(编者按:这很常见;大多数现实生活中的C实现都是这样工作的。这就是为什么std::is\u always\u lock\u free如此有用的原因:因为它通常适用于is\u lock\u free()始终为真的类型。)

黄鸣
2023-03-14

您可以使用标准:is\u always\u lock\u free

是否无锁取决于实际系统,无法在编译时确定。

相关说明:

原子类型有时也允许是无锁的,例如,如果给定体系结构上只有对齐的内存访问自然是原子的,那么相同类型的未对齐对象必须使用锁。

韩夕
2023-03-14

如cppreference上所述:

除了std::atomic\u标志之外的所有原子类型都可以使用互斥锁或其他锁定操作来实现,而不是使用无锁原子CPU指令。原子类型有时也允许是无锁的,例如,如果给定体系结构上只有对齐的内存访问自然是原子的,那么相同类型的未对齐对象必须使用锁。

C标准建议(但不要求)无锁原子操作也是无地址的,即适用于使用共享内存的进程之间的通信。

正如许多其他人所提到的,std::is\u always\u lock\u free可能是您真正想要的。

编辑:为了澄清这一点,C对象类型有一个对齐值,该值将其实例的地址限制为二次幂的某些倍数([基本.对齐])。这些对齐值是为基本类型定义的实现,不必等于类型的大小。它们也可以比硬件实际支持的更严格。

例如,x86(大部分)支持未对齐的访问。但是,对于x86,您会发现大多数编译器都具有alignof(double)=sizeof(double)==8,因为未对齐的访问有许多缺点(速度、缓存、原子性…)。但例如,pragma pack(1)struct X{char a;double b;} 或<代码>对齐(1)双x允许您使用“unaligned”(未对齐)双s。因此,当cppreference谈到“对齐内存访问”时,它可能是根据硬件类型的自然对齐来实现的,而不是以与对齐要求(即UB)相矛盾的方式使用C类型。

以下是更多信息:在x86上成功取消对齐访问的实际效果如何?

还请查看以下@Peter Cordes的深刻评论!

 类似资料:
  • 我知道是一个原子对象。但是原子化到什么程度呢?据我所知,操作可以是原子的。使一个对象原子化到底是什么意思?例如,如果有两个线程同时执行以下代码: 那么整个操作(例如)是原子操作吗?还是对变量atomic(so)进行了更改?

  • 这是有效代码: 但是在这里,我真的很想声明和 。但是为什么呢?

  • 当您尝试在中使用Constexpr时,如下所示: gcc和clang投诉: 错误:无法将::main声明为内联 错误:'main'不允许声明为constexr 让我们看看constexpr函数的要求是什么: constexpr函数必须满足以下要求: 它必须不是虚拟的 它的返回类型必须是文学类型 它的每个参数都必须是文字类型 什么是文学类型? 文字类型是以下任一类型 void(自c 14起) 功能体

  • 为什么在Java中不是原子的? 为了更深入地了解Java我试图计算线程中的循环执行的频率。 所以我用了 在主课上。 我有两条线。 线程1:打印

  • 如果变量是易变的,那么显然没有任何优化是适用的。在我的情况下是什么阻止了它? 下面是编译器资源管理器中的代码。

  • 基于 Swoole 提供的 Swoole\Atomic,直接在配置文件中设置,就可以在worker进程中使用,数据互通。 使用时无需加锁! 配置方式 在项目配置文件中加入以下节 'atomics' => [ // 定义名为name1的,初始值为0 'name1', // 定义名为name2的,初始值为10 'name2' => 10, ],