Search code examples
multithreadingdelphidelphi-xe5

Is This Implementation of AnonymousThread Correct?


The MCVE describing the idea is the following. There is an array of classes/records that have a method that takes an input parameter and calculates some result that is stored in one of its variables:

type
  TMyRecord = record
    FLastResult: double;
    procedure DoHeavyMath(Input: double);
  end;
var
  MyRecordArray:array [0..999] of TMyRecord;
  InputData:array [0..999] of double;
implementation

procedure TMyRecord.DoHeavyMath(Input: double);
begin
  FLastResult:=Input;//Here should be some math
end;

I am creating anonymous threads and limit the number of processes (threads) working simultaneously.

procedure TForm1.Button1Click(Sender: TObject);
var
  ThreadsCounter, i: word;
begin
  ThreadsCounter := 0;

  for i := 0 to 999 do
  begin
    while ThreadsCounter >= 4 { or other limit } do
    begin
    end;

    inc(ThreadsCounter);
    TThread.CreateAnonymousThread(
      procedure
      begin
        MyRecordArray[i].DoHeavyMath(InputData[i]);
        dec(ThreadsCounter)
      end).Start;
  end;
  repeat
  until ThreadsCounter = 0;
  // return to main thread tasks
end;

Is this threads' implementation correct?


Solution

  • No it is not correct. There is a data race on ThreadsCounter. Use an atomic function instead, for instance AtomicDecrement.

    The performance won't be very good because you incur significant overhead when creating a thread. Use a thread pool instead so that threads can be re-used. The busy loops aren't going to help performance one bit.