gpt4 book ai didi

multithreading - 自动或手动释放 TThread

转载 作者:行者123 更新时间:2023-12-03 14:43:20 24 4
gpt4 key购买 nike

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

我了解 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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com