2017-04-22 7 views
11

Delphi 10.2(Linux対応)には、Windows InterlocekdEchangeと同等のクロスプラットフォーム関数AtomicExchangeがあります。これまでのところとても良いです...Delphi 10.2を使用するLinux用のInterlockedExchangeAddに相当)

私は、AtomicExchangeAdd同等物を持たないInterlockedExchangeAddを使用してWin32コードを移植する必要があります。

私の質問は、Linux用にコンパイルするときにInterlockedExchangeAddを置き換えるのに何が使えますか?

+0

http://stackoverflow.com/q/2287451/505088 –

答えて

10

InterlockedExchangeAdd()「値に値の原子の添加を行うには、加数によって指される。結果は、加数で指定されたアドレスに格納されています。」相互に整数値をインクリメント

System.SyncObjsユニットが同じことを行うためにAdd()方法をオーバーロードしているTInterlockedクラスを有しています。

オーバーロードされたAddのメソッドが2つあります。両方のAddメソッドは、TargetIncrementだけインクリメントします。

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()あるTInterlocked.Add()代わりに「インクリメントパラメータの値を返す」に対し、「変数の初期値が加算によって指さ戻り」。だから、あなたは戻り値を使用している場合、あなたはその違いを考慮する必要があります、例えば:

function InterlockedExchangeAdd(var Addend: Integer; Value: Integer): Integer; 
begin 
    Result := TInterlocked.Add(Addend, Value) - Value; 
end; 
+0

本当に連動(原子)は、このですか?ちなみに、TInterlockedはAtomicXYZ関数のラッパーです。 – fpiette

+0

@fpietteはい、それはラッパーですが、アトミック操作のためのパブリッククロスプラットフォームインターフェースです。 –

+1

'AtomicIncrement'などもパブリックなクロスプラットフォームです。どちらかを選ぶことができます。 –

11

System.SysUtils.pasでこの関数の隠された実装があります:

function AtomicExchangeAdd(var Addend: Integer; Value: Integer): Integer; 
begin 
    Result := AtomicIncrement(Addend, Value) - Value; 
end; 

それは事実を利用することの新しい値を返しますAtomicIncrement、しばらくInterlockedExchangeAddは古い値を返します。 の値を減算すると、期待される結果が得られ、明らかにスレッドセーフです。

関連する問題