Thread-safe way to increment and return an integer in Delphi
In a single-threaded application I use code like this:
Interface
function GetNextUID : integer;
Implementation
function GetNextUID : integer;
const
cUID : integer = 0;
begin
inc( cUID );
result := cUID;
end;
This could开发者_Python百科 of course be implemented as a singleton object, etc. - I'm just giving the simplest possible example.
Q: How can I modify this function (or design a class) to achieve the same result safely from concurrent threads?
You can use the Interlocked*
functions:
function GetNextUID : integer;
{$J+} // Writeble constants
const
cUID : integer = 0;
begin
Result := InterlockedIncrement(cUID);
end;
More modern Delphi versions have renamed these methods into Atomic*
(like AtomicDecrement
, AtomicIncrement
, etc), so the example code becomes this:
function GetNextUID : integer;
{$J+} // Writeble constants
const
cUID : integer = 0;
begin
Result := AtomicIncrement(cUID);
end;
The easiest way would probably be to just call InterlockedIncrement
to do the job.
With modern Delphi compilers it is better to use Increment function of class TInterlocked from unit System.SyncObjs. Something like this:
type
TMyClass = class
class var
FIdCounter: int64;
var
FId: int64;
constructor Create;
end;
constructor TMyClass.Create;
begin
FId := TInterlocked.Increment(FIdCounter);
end;
This helps to keep the code platform-independent.
精彩评论