代码之家  ›  专栏  ›  技术社区  ›  Marek Jedliński

线程安全的增量和返回Delphi中整数的方法

  •  14
  • Marek Jedliński  · 技术社区  · 14 年前

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

    Interface
        function GetNextUID : integer;
    Implementation
        function GetNextUID : integer;
        const
          cUID : integer = 0;
        begin
          inc( cUID );
          result := cUID;
        end;
    

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

    问:如何修改这个函数(或设计一个类)以安全地从并发线程中获得相同的结果?

    3 回复  |  直到 7 年前
        1
  •  37
  •   Jeroen Wiert Pluimers    7 年前

    您可以使用 Interlocked* 功能:

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

    更现代的Delphi版本将这些方法重命名为 Atomic* (像 AtomicDecrement , AtomicIncrement 等),因此示例代码变为:

        function GetNextUID : integer;
        {$J+} // Writeble constants
        const
          cUID : integer = 0;
        begin
          Result := AtomicIncrement(cUID);
        end;
    
        2
  •  15
  •   Jerry Coffin    14 年前

    最简单的方法可能是打电话 InterlockedIncrement 做这项工作。

        3
  •  5
  •   Andrei Galatyn    9 年前

    使用现代Delphi编译器时,最好使用 Increment 类的功能 TInterlocked 来自Unit System.Syncobjs。像这样:

      type
        TMyClass = class
        class var
          FIdCounter: int64;
        var
          FId: int64;
        constructor Create;
        end;
    
    constructor TMyClass.Create;
    begin
      FId := TInterlocked.Increment(FIdCounter);
    end;
    

    这有助于保持代码平台的独立性。