zed
1#
zed Published in 2018-02-12 12:04:45Z
 In my application several threads increment some counter and only one reads this value (main thread). As far I know, reading 32-bit value is thread-safe if it is aligned by double word, so I use such code: {\$A8} TMyStat = class private FCounter: Integer; public procedure IncCounter; property Counter: Integer read FCounter; ... procedure TMyStat.IncCounter; begin InterlockedIncrement(FCounter); end;  But I'm not sure that it's safe to mix Interlocked functions and direct access to value. Should I use InterlockedCompareExchange instead? function TMyStat.GetCounter: Integer; begin Result := InterlockedCompareExchange(FCounter, 0, 0); end; 
gabr
2#
 You can use a normal read. As FCounter is 4-aligned, reading and writing is guaranteed to be atomic. [This holds for Intel platforms, though. I really don't know how ARM behaves. I would guess that the behaviour is the same (reading of aligned value is atomic).] Actually, if you only increment a counter and read it, you don't even need InterlockedIncrement. When you read the value you'll always get either the pre-increment or post-increment value. There's no way you get a mix of both.
 Reading an aligned 32-bit value is atomic (i.e. all 32 bits are guaranteed to be consistent). But the read is not synchronized. You may not read the "current" value; but instead a value from the caches. For example: FCounter := 1; //number of threads running FResult := 0; //the answer to everything  And then your thread: procedure ThreadProc; begin FResult := 42; //set the answer before we indicate we're done InterlockedDecrement(FCounter); end;  And then your code checks that the thread is done: if (FCounter <= 0) then begin //Thread is done; read the answer ShowMessage('The answer is: '+IntToStr(FResult)); Exit; end;  The answer is: 0 Even though your flag said the thread set the result, you read the result value out of your local cache. Even though the read of FCounter and FResult is atomic they aren't synchronized If you are only using FCounter then you are fine. But as soon as you use anything else and expect them to be consistent, then you need to also use something to enforce synchronization. The strict answer to your question is that reading a 32-bit aligned value is already an atomic operation. But it's entirely possible that people coming here to read this question might forget that the read being atomic is a small part of your worries.