multithreading - 自动或手动释放 TThread

标签 multithreading delphi delphi-7 tthread

我的程序中有一个主线程和一个单独的线程。如果单独的线程在主线程之前完成,它应该自动释放自身。如果主线程先完成,它应该释放单独的线程。

我了解 FreeOnTerminate,并且我读到您必须小心使用它。

我的问题是,下面的代码正确吗?

procedure TMyThread.Execute;
begin
  ... Do some processing

  Synchronize(ThreadFinished);

  if Terminated then exit;

  FreeOnTerminate := true;
end;

procedure TMyThread.ThreadFinished;
begin
  MainForm.MyThreadReady := true;
end;

procedure TMainForm.Create;
begin
  MyThreadReady := false;

  MyThread := TMyThread.Create(false);
end;

procedure TMainForm.Close;
begin
  if not MyThreadReady then
  begin
    MyThread.Terminate;
    MyThread.WaitFor;
    MyThread.Free;
  end;
end;

最佳答案

您可以将其简化为:

procedure TMyThread.Execute;
begin
  // ... Do some processing
end;

procedure TMainForm.Create;
begin
  MyThread := TMyThread.Create(false);
end;

procedure TMainForm.Close;
begin
  if Assigned(MyThread) then
    MyThread.Terminate;
  MyThread.Free;
end;

说明:

  • 使用 FreeOnTerminate 或手动释放线程,但切勿同时执行这两种操作。线程执行的异步性质意味着您面临不释放线程或(更糟糕的是)执行两次的风险。在执行完成后保留线程对象没有风险,并且在已经完成的线程上调用 Terminate() 也没有风险。

  • 无需同步对仅从一个线程写入并从另一个线程读取的 bool 值的访问。在最坏的情况下,您会得到错误的值,但由于异步执行,无论如何这是一个虚假的效果。仅对于无法原子读取或写入的数据才需要同步。如果您需要同步,请不要使用 Synchronize()

  • 不需要有类似于MyThreadReady的变量,因为您可以使用 WaitForSingleObject()询问线程的状态。将 MyThread.Handle 作为第一个参数,将 0 作为第二个参数传递给它,并检查结果是否为 WAIT_OBJECT_0 - 如果是,则您的线程有执行完毕。

顺便说一句:不要使用 OnClose 事件,而是使用 OnDestroy 事件。前者不一定被调用,在这种情况下,您的线程可能会继续运行并使进程保持事件状态。

关于multithreading - 自动或手动释放 TThread,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3557105/

相关文章:

c++ - 访问列表项时的 UI 和工作线程同步

delphi - XE2如何自动保存?

delphi - 在 Delphi 中编译/链接未使用的函数/过程

python - python 线程或多处理是异步调用的核心吗?

Python - Flask-SocketIO 从线程 : not always working 发送消息

delphi - 发现链接到数据集字段的数据感知控件

delphi - 如何禁用 Delphi 中的所有异常引发?

delphi - 我的插入语句中出现语法错误

delphi - StrToFloat 在我的应用程序中引发错误,而不是在任何应用程序中引发错误

multithreading - 使用 lisp 实现计算器程序