简体   繁体   中英

Delphi XE7 Android Creating Thread Error After Running about 2000000 times

thanks ahead for your time.

Simple code post at first.

code of TSubThread

TSubThread = class(TThread)
protected
  procedure Execute; override;
public
  constructor Create;
  destructor Destroy; override;
end;

procedure TSubThread.Execute;
begin
// do nothing
end;

constructor TSubThread.Create;
begin
  inherited Create(True);
  Self.FreeOnTerminate:= False;
end;

code of TMainThread

TMainThread = class(TThread)
private
  FCounterOK,
  FCounterErr:int64;
  function FGetCounterOK:Int64;
  function FGetCounterErr:Int64;
protected
  procedure Execute; override;
public
  property CountOK:Int64 read FGetCounter;
  property CountErr:Int64 read FGetCounterErr;
  constructor Create;
  destructor Destroy; override;
end;

function TMainThread.FGetCounterOK:Int64;
begin
  result:= TInterlocked.Read(Self.FCounterOK);
end;

function TMainThread.FGetCounterErr:Int64;
begin
  result:= TInterlocked.Read(Self.FCounterErr);
end;

procedure TMainThread.Execute;
const
  CSTMaxThreads = 20;
var
  i: Integer;
  los:TArray<TSubThread>;
begin
  try
    while not Self.Terminated do
    begin
      //Create instance of TSubThread and append to DynArray
      while Length(los) < CSTMaxThreads do
      begin
        try
          l:= TSubThread.Create;
          los:= los + [l];
          l.Start;
          TInterLocked.Increment(Self.FCounterOK);
        except on E:System.SysUtils.Exception do
          TInterLocked.Increment(Self.FCounterErr);
        end;
      end;

      for i:= Length(los)-1 downto 0 do
      begin
      // Free thread Object
        if los[i].Finished then
        begin
          los[i].DisposeOf;
          los[i]:= nil;
          Delete(los,i,1);
        end;
      end;

    end;

  finally
    // MainThread  Terminated, Free all.
    for i := Length(los)-1 downto 0 do
    begin
      los[i].DisposeOf;
      los[i]:= nil;
    end;
    delete(los,0,Length(los));
  end;
end;

The creation of TSubThread raise exception after running about 1800000 ~ 2000000 times (by CounterOK and CounterErr property) on Android platform with E.ToString = "Create error: Try again."... and the same program runs perfect on Windows and IOS. Is there somewhere wrong with the code?

I'm fairly sure the problem here is that you are spawning far too many threads and running out of resources to support their existence. TThread sets finished once Execute has finished but before the actual underlying thread has been cleaned up. DisposeOf will call the destructor but this still only uses WaitFor which checks for finished and hence may still leave outstanding cleanup for the underlying thread. There have always been problems with managing the destruction of threads on all platforms and I'm pretty sure you will find this is what is happening here. For a long, long time I have resorted to always operating a thread pool with internal reuse and freeonterminate true to avoid these sorts of issues.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM