谁能告诉我是否是原子的
为什么它没有像C 17一样设计呢?首先,它总是\u lock\u free吗?
我已经在我的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()
始终为真的类型。)
您可以使用标准:is\u always\u lock\u free
是否无锁取决于实际系统,无法在编译时确定。
相关说明:
原子类型有时也允许是无锁的,例如,如果给定体系结构上只有对齐的内存访问自然是原子的,那么相同类型的未对齐对象必须使用锁。
如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, ],