Ein Problem bekommt man nur, wenn man vergisst, dass die unterschiedlichen Prozessoren (ohne InterLocked) unterschiedliche Ansichten des Arbeitspeichers haben können (durch asynchrone Caches).
Beispiel aus dem
PSDK...
Delphi-Quellcode:
var
Value: Integer;
ValueHasBeenComputed: LongBool = False;
procedure CacheComputedValue;
begin
if not ValueHasBeenComputed then
begin
Value := ComputeValue();
ValueHasBeenComputed := True;
end;
end;
function FetchComputedValue(out Val: Integer): LongBool;
begin
if ValueHasBeenComputed then
begin
Val := Value;
Result := True;
end
else
Result := False;
end;
Das Problem ist hier... ein Thread der gerade CacheComputedValue aufruft und ValueHasBeenComputed setzt und mit den anderen Prozessoren synchronisiert hat, muss nicht zwingend den neuen Wert von Value in die gemeinsame Speicheransicht übertragen haben (auch wenn die Befehle hintereinander stehen!). Ein zweiter Thread (auf einem anderen Prozessor) könnte also ValueHasBeenComputed = True 'sehen' aber noch nicht den neuen Wert von Value.
Erst durch die Interlocked/Wait/CriticalSection/Synchronisations-Funktionen werden die Caches der Prozessoren synchronisiert.
Delphi-Quellcode:
procedure CacheComputedValue;
begin
if not ValueHasBeenComputed then
begin
Value := ComputeValue();
InterlockedExchange(ValueHasBeenComputed, True);
end;
end;
Ergo: Lesen ohne Probleme, Setzen mit Interlocked.
ps: welche Operationen 'atomar' sind und welche nicht, steht in den jeweiligen Prozessor-Beschreibungen... grobe Richtlinie: Integer-Operationen die nur eine Prozessoranweisung benötigen.