在Delphi中以线程安全的方式增加和返回一个整数

Mar*_*ski 14 delphi multithreading increment thread-safety

在单线程应用程序中,我使用如下代码:

Interface
    function GetNextUID : integer;
Implementation
    function GetNextUID : integer;
    const
      cUID : integer = 0;
    begin
      inc( cUID );
      result := cUID;
    end;
Run Code Online (Sandbox Code Playgroud)

这当然可以作为单个对象实现,等等 - 我只是给出了最简单的例子.

问:如何修改此函数(或设计类)以从并发线程安全地实现相同的结果?

And*_*den 37

你可以使用这些Interlocked*功能:

    function GetNextUID : integer;
    {$J+} // Writeble constants
    const
      cUID : integer = 0;
    begin
      Result := InterlockedIncrement(cUID);
    end;
Run Code Online (Sandbox Code Playgroud)

更现代的德尔福版本已经改名这些方法为Atomic*(如AtomicDecrement,AtomicIncrement等),所以示例代码变成这样:

    function GetNextUID : integer;
    {$J+} // Writeble constants
    const
      cUID : integer = 0;
    begin
      Result := AtomicIncrement(cUID);
    end;
Run Code Online (Sandbox Code Playgroud)

  • 和+1表示明确陈述{$ J +}.虽然我更喜欢将GetNextUID作为类函数并使用类var来实现FUID,因为我不喜欢滥用常量. (5认同)

Jer*_*fin 15

最简单的方法可能是打电话InterlockedIncrement来完成这项工作.


And*_*tyn 5

使用现代Delphi编译器,最好从System.SyncObjs单元使用TInterlocked类的Increment函数.像这样的东西:

  type
    TMyClass = class
    class var
      FIdCounter: int64;
    var
      FId: int64;
    constructor Create;
    end;

constructor TMyClass.Create;
begin
  FId := TInterlocked.Increment(FIdCounter);
end;
Run Code Online (Sandbox Code Playgroud)

这有助于保持代码平台无关.