在Thread派生类中创建一个Thread

时间:2012-11-26 09:30:20

标签: multithreading delphi delphi-7 tthread

我创建了一个派生自TThread类的新类,并在构造函数上调用“inherited Create(True);”,然后调用“Resume()”,因为我已经覆盖了Execute()调用,现在我想回忆一下执行()(再次运行线程)而不破坏类实例,所以我在新类中有一个名为“myRestart()”的函数,它回忆“继承的Create(True);”并且让我能够再次调用“Resume()”并且线程再次工作。

我的问题是,这是一种安全的做法吗?如果我有这个类的多个实例,它会工作吗?或者有更好的方法吗?

感谢

2 个答案:

答案 0 :(得分:4)

不要四处走动。如果您希望线程类中的过程/函数多次运行,请在Execute覆盖中的while()循环中调用它们,并通过顶部的信号量或事件,通过合适的同步对象运行代码来运行代码,说:

TmyThread.Execute;
begin
  while true do
  begin
    someEvent.waitFor(INFINITE);
    if terminated then exit;
    doMyProcedure(params);
    doOtherStuff;
  end;
end;

答案 1 :(得分:-1)

我认为您必须显示重启代码? 因为我知道线程是否完成它的执行程序然后它在操作系统中的状态将更改为DONE并再次调用resume仅将该线程作为主线程中的函数启动而不是真正的单独线程。

顺便说一下,您可以根据需要使用此示例代码

unit UWorker;

interface

uses Windows, Classes, Contnrs;

type
  TWorkerThread=class;

  TWorkerJob=class
    procedure ExecuteJob(Worker: TWorkerThread); virtual; abstract;
  end;

  TWorkerThread=class(TThread)
  private
    FFinished: TObjectList;
    FNotFinished: TObjectList;
  protected
    procedure Execute;Override;
  public
    constructor Create(createSuspended: Boolean);override;
    destructor Destroy; override;
  public
    property Finished: TObjectList read FFinished;
    property NotFinished: TObjectList read FNotFinished;
  end;



implementation

{ TWorkerThread }

constructor TWorkerThread.Create(createSuspended: Boolean);
begin
  inherited;
  FFinished := TObjectList.Create;
  FNotFinished := TObjectList.Create;
end;

destructor TWorkerThread.Destroy;
begin
  FFinished.Free;
  FNotFinished.Free;
  inherited;
end;

procedure TWorkerThread.Execute;
var
  CurrentJob: TWorkerJob;
begin
  while not Terminated do
  begin
    if FNotFinished.Count > 0 then
    begin
      CurrentJob := TWorkerJob(FNotFinished.Items[0]);
      FNotFinished.Extract(CurrentJob);

      with CurrentJob do
      begin
        ExecuteJob(Self);
      end;
      FFinished.Add(CurrentJob);
    end else
    begin
      // pass the cpu to next thread or process
      Sleep(5);
    end;
  end;

end;

end.

使用此代码只需创建一个worker然后创建一些作业实例并将它们添加到NotFinished列表中。工人将逐个执行所有工作。 要重新启动作业,只需从完成列表中提取它,然后将其再次添加到NotFinished。

记住你必须继承你的工作并覆盖ExecuteJob程序。