对无符号变量的原子操作函数
使用Interlocked* 函数或TInterlocked原子地写入无符号变量的安全且正确的方法是什么?
在下方的函数中,(A) 和 (B) 是否完全原子性且线程安全?还是需要 (C) 或 (D)?
procedure TForm1.Button3Click(Sender: TObject);
var
tLastReload: UInt64;
begin
TInterlocked.Exchange(Int64(tLastReload),1); //A
InterlockedExchange64(Int64(tLastReload),2); //B
TInterlocked.Exchange(PInt64(@tLastReload)^,3); //C
InterlockedExchange64(PInt64(@tLastReload)^,4); //D
end;
解决方案
Win32 API的 Interlocked... API并不会直接接受无符号变量,因此需要进行指针类型转换。在你的示例中,A 和 C 在功能上是等价的,B 和 D 也在功能上等价。
不过,TInterlocked.Exchange() 确实为无符号类型 Cardinal 和 UInt64 提供了重载:
class function Exchange(var Target: Cardinal; Value: Cardinal): Cardinal; overload; static; inline;
class function Exchange(var Target: UInt64; Value: UInt64): UInt64; overload; static; inline;
Interlocked操作,无论通过 TInterlocked 还是 Interlocked... API,都是完全原子且线程安全的,对吗?
1: 前提是它们对整个变量进行操作,而不是将操作拆分开来,即对一个64位变量使用两次32位交换等。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。