使用Delphi 10.2在Linux上的InterlockedExchangeAdd等效方法

11

Delphi 10.2(支持Linux)具有跨平台函数AtomicExchange,它相当于Windows的InterlockedExchange。到目前为止还好...

我必须将使用InterlockedExchangeAdd的Win32代码移植,但没有AtomicExchangeAdd等效物。

我的问题是:在编译Linux时,我可以用什么来替换InterlockedExchangeAdd?


https://dev59.com/rnE95IYBdhLWcg3wf98F - David Heffernan
2个回答

11

System.SysUtils.pas中有一个隐藏的实现该函数的方法:

function AtomicExchangeAdd(var Addend: Integer; Value: Integer): Integer;
begin
  Result := AtomicIncrement(Addend, Value) - Value;
end;
它利用 AtomicIncrement 返回 Addend 的新值,而 InterlockedExchangeAdd 返回旧值的事实。减去 Value 可以得到预期结果并且显然是线程安全的。

10

InterlockedExchangeAdd()函数 "将Value原子地加到指向的Addend值中。结果存储在由Addend指定的地址中。"

System.SyncObjs单元有一个TInterlocked类,该类有重载的Add()方法可以执行同样的操作:

增加整数值。

有两个重载的Add方法。这两个Add方法都会将Increment增加到Target中。

class function Add(var Target: Integer; Increment: Integer): Integer; overload; static; inline;

class function Add(var Target: Int64; Increment: Int64): Int64; overload; static; inline;

区别在于InterlockedExchangeAdd()“返回Addend指向的变量的初始值”,而TInterlocked.Add()“返回增加后的参数的值”。因此,如果您使用返回值,您必须考虑到这种差异,例如:
function InterlockedExchangeAdd(var Addend: Integer; Value: Integer): Integer;
begin
  Result := TInterlocked.Add(Addend, Value) - Value;
end;

这真的是互锁(原子操作)吗?顺便说一下,TInterlocked只是AtomicXYZ函数的包装器。 - fpiette
@fpiette 是的,它是一个包装器,但它也是一个公共的跨平台原子操作接口。 - Remy Lebeau
1
AtomicIncrement等也是公共跨平台的。您可以选择任何一个。 - David Heffernan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接