对无符号变量的原子操作函数

后端开发 2026-07-09

使用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并不会直接接受无符号变量,因此需要进行指针类型转换。在你的示例中,AC 在功能上是等价的,BD 也在功能上等价。

不过,TInterlocked.Exchange() 确实为无符号类型 CardinalUInt64 提供了重载:

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导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章