对于从XE2到XE8的Delphi编译器,对于非windows目标平台,用[Volatile]注释的整数数据成员的读取操作是原子的吗?
我知道对于 Windows 平台的情况,当且仅当数据成员对齐到 4 字节时它是原子的,但是非 Windows(Android 等)呢?
请注意,我不是在询问线程安全性。线程安全和原子性是两个不同的东西。
最佳答案
LU RD 的评论是正确答案。
非 Windows 的工作方式与 Windows 类似,当且仅当数据成员是 32 位对齐时,读取操作才是原子的。在一般情况下,您不能依赖它是原子的,因为您不知道对齐方式,但在特定情况下,您控制数据成员的声明,您可以使用 {$ALIGN 4} 或 { $ALIGN 8} 本地指令以保证对齐。
示例,
{$IFDEF POSIX}
{$ALIGN 4}
type
TMyClass = class
[Volatile] FValue: integer;
end;
{$ENDIF}
...上面的FValue可以被原子读取。 (不做任何关于线程安全的声明)。
在更一般的情况下,FValue 的对齐方式未知,读取 FValue 可能并不总是原子的,并且需要类似于以下代码的内容...
ReadOfValue := TInterlocked.CompareExchange( FValue, 0, 0);
上面有一个警告:TInterlocked 类可能不适用于某些编译器。我不确定它是什么时候引入的。可能是XE7。
<小时/>更新
感谢 David Heffernan 和 Gabr 的以下评论,我声明上述代码无法在非 Windows 平台上可靠地工作。保证正确对齐的唯一方法是使用指针算术。 OmniThreadLibrary 中的 GpStuff 单元有效地使用指针算术来提供原子可读的整数值。
可能 [Volatile] 属性没有帮助,但您也可以说它没有坏处,甚至可能有语义上的好处或代码阅读器。
关于delphi - Delphi 中整数读取是原子的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29958168/