Aquire Singleton class Instance Multithread
Aby uzyskać instancję klasy ze wzorem Singleton, chcę użyć następującej funkcji:
To jest szkic
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.
Trzy pytania:
1- Czy ten projekt jest bezpieczny? Zwłaszcza z częścią InterlockedExchange.
2- Jak korzystać z InterlockedCompareExchange? Czy można zrobić to, co próbuję?
3- Czy ten projekt jest lepszy niż cały kod w krytycznym zakresie sekcji?
Uwaga: Mój obiekt jest bezpieczny dla wątków, tylko konstrukcja, którą muszę serializować!
To nie jest intire code, tylko ważna część, to znaczy funkcja getInstance.
I POTRZEBA użyć jakiegoś obiektu singleton.
Czy istnieje sposób użycia InterlockedCompareExchange do porównania, jeśli wartość InstanceNumber wynosi zero?
I
1 - Utwórz obiekt tylko wtedy, gdy jest 0, w przeciwnym razie zwróć instancję.
2 - Gdy wartość wynosi 0: Wprowadź w sekcji krytycznej. Utwórz obiekt. Opuść sekcję krytyczną.
3 - Czy lepiej byłoby zrobić to w ten sposób, zamiast angażować cały kod w krytycznym zakresie sekcji?