Sharing Native variable between Delphi threads

I assumed that if a common variable between threads has its own type, atomicity should do the job.

But according to the output of the code below, this is not the case, at least for delphi.

Thread t1 just increments the counter 10M times. At the same time, thread t2 decreases the counter 10M times. So the expected value of the counter at the end is 0, but each time I read different values.

What is the correct way to share an inline variable between threads in Delphi without blocking?

procedure TForm1.Button1Click(Sender: TObject);
var
  t1, t2: TThread;
  Counter: NativeInt;
begin
  Counter := 0;

  // first thread to increment shared counter
  t1 := TThread.CreateAnonymousThread(
    procedure ()
    var
      i: Integer;
    begin
      for i := 1 to 10000000 do
        Inc(Counter);
    end
  );

  // second thread to decrement shared counter
  t2 := TThread.CreateAnonymousThread(
    procedure ()
    var
      i: Integer;
    begin
      for i := 1 to 10000000 do
        Dec(Counter);
    end
  );

  t1.FreeOnTerminate := false;
  t2.FreeOnTerminate := false;

  // start threads
  t1.Start;
  t2.Start;

  // wait for them to finish
  t1.WaitFor;
  t2.WaitFor;

  t1.Free;
  t2.Free;

  // print the counter, expected counter is 0
  Caption := IntToStr(Counter);
end;
+4
source share
1 answer

. , inc dec . , .

. TInterlocked AtomicIncrement.

NativeInt, . , . 32 32- , 64 64- . Delphi, , , .

+3

Source: https://habr.com/ru/post/1692553/


All Articles