シングルトン パターンを持つクラスのインスタンスを取得するには、次の関数を使用します。
これはスケッチです
interface
uses SyncObjs;
type
TMCriticalSection = class(TCriticalSection)
private
Dummy : array [0..95] of Byte;
end;
var
InstanceNumber : Integer;
AObject: TObject;
CriticalSection: TMCriticalSection;
function getInstance: TObject;
implementation
uses Windows;
function getInstance: TObject;
begin
//I Want somehow use InterlockedCompareExchange instead of CriticalSession, for example
if InterlockedCompareExchange(InstanceNumber, 1, 0) > 0 then
begin
Result := AObject;
end
else
begin
CriticalSection.Enter;
try
AObject := TObject.Create;
finally
CriticalSection.Leave;
end;
InterlockedIncrement(InstanceNumber);
Result := AObject
end;
end;
initialization
CriticalSection := TMCriticalSection.Create;
InstanceNumber := 0;
finalization;
CriticalSection.Free;
end.
3 つの質問:
1- このデザインはスレッドセーフですか? 特にInterlockedExchangeパーツ付き。
2- InterlockedCompareExchange の使用方法は? 私がしようとしていることをすることは可能ですか?
3- この設計は、クリティカル セクションの範囲内にすべてのコードを含めるよりも優れていますか?
注意: 私のオブジェクトはスレッド セーフです。シリアル化する必要があるのは構造だけです!
これはコード全体ではなく、重要な部分、つまり getInstance 関数だけです。
編集
ある種のシングルトン オブジェクトを使用する必要があります。
InstanceNumber の値がゼロの場合、InterlockedCompareExchange を使用して比較する方法はありますか?
And
1 - が 0 の場合にのみオブジェクトを作成し、それ以外の場合はインスタンスを返します。
2 - 値が 0 の場合: クリティカル セクションに入力します。オブジェクトを作成します。クリティカル セクションを残します。
3 - クリティカル セクションのスコープ内にすべてのコードを含めるのではなく、この方法で行う方がよいでしょうか?