Form1.OnDestroy
事件处理程序中调用TThread.Terminate
方法来正确终止线程,但是终止需要一些时间,因此我无法释放内存(通过TThread.Free
方法)。
不幸的是,由于某种其他原因,我必须将TThread.FreeOnTerminate
属性设置为false,因此线程对象在线程终止后不会自动销毁。我的问题可能有点傻,我早就应该知道它了,但这样做是否正常并且线程将自动销毁(因为应用程序只是结束),还是存在问题并且内存将被“丢失”?感谢您的解释。
Form1.OnDestroy
事件处理程序中调用TThread.Terminate
方法来正确终止线程,但是终止需要一些时间,因此我无法释放内存(通过TThread.Free
方法)。
不幸的是,由于某种其他原因,我必须将TThread.FreeOnTerminate
属性设置为false,因此线程对象在线程终止后不会自动销毁。在关闭应用程序的其余部分之前,您应该等待线程终止,否则共享资源可能会在线程结束时被释放,从而可能导致一系列访问冲突。等待线程终止后,您可以释放它。实际上,这就是TThread
析构函数为您完成的。
如果没有共享资源,那么当然可以让它自行死亡。即使线程在主线程之后终止,只要所有线程退出,程序就会终止。与线程对象相关联的任何内存都将随其他内容一起被清理并返还给操作系统。
但是,要小心!如果您的线程需要花费很长时间才能退出,它可能会成为僵尸进程,一直在运行而没有GUI界面。这就是为什么在线程循环中非常重要的检查Terminated
标志,并退出线程。
N@
TThread
以来,析构函数已经自己调用了 Terminate
和 WaitFor
。简单的 Free
(或 FreeAndNil
)就足够了。如果线程类有一个重载的析构函数,它应该在其中调用 Terminate
和 WaitFor
,因为它不能在线程过程结束之前销毁字段。把所有这些留给线程类的用户太危险了。 - mghieTThread
析构函数中挂起的情况,因为线程已经终止,但它又试图再次终止它(等待无限时间以进行永远不会发生的关闭),因此需要这段代码。也许我在线程终止和线程清理代码执行之间捕捉到了该线程。 - Nat当一个进程终止时,操作系统将回收所有分配的内存并关闭所有打开的句柄。在关闭应用程序的非常特殊的情况下,您不需要担心内存泄漏问题。操作系统也会关闭所有打开的句柄,至少在理论上是这样的。考虑到所有这些因素,您可以安全地在窗体析构函数中终止线程(使用TerminateThread(MyThread.Handle)),然后再杀死其他共享资源。请问自己以下几个问题:
如果两者都很安全,您可以使用TerminateThread而不必等待线程自然终止。更安全的方法可能是综合方法,也许您应该给线程一个自然终止的机会,如果它在5秒内没有终止,则强制终止它。
*) 我在谈论那些只能在进程终止时才能证明泄漏的内存,例如你杀死而没有给予适当关闭机会的线程,或者你不释放的全局单例类。所有其他未记录的内存都需要被追踪并修复,因为它是一个错误。
**) 不幸的是,Windows 操作系统并非无错。例如:任何在 Windows 平台上使用串行设备的人都知道它有多容易陷入“锁定”状态,需要重新启动才能使其正常工作。从技术上讲,这也是一个句柄,结束锁定它的应用程序应该解锁它。
为什么在创建线程时不增加一个变量,在销毁事件中等待线程完成,然后减少变量,在应用程序终止时只需执行Application.processmessages?
为什么您的线程不是freeonterminate=true?所有共享资源都可以处理到关键部分。
此致敬礼,
TThread.Terminate
方法通过设置Terminated
标志实际上实现了退出操作,当你在代码中检查这个标志时,就是一个退出信号。 - NatWaitFor
方法...所以在FormDestroy
中,我只需请求线程终止(在线程的Execute
方法中我经常检查Terminated
,所以我知道它真的会终止),然后就完成了...这就是为什么我提出了这个问题...非常感谢所有的回答和评论,它们对我帮助很大... - Ondra C.FreeOnTerminate
设置为 true 并在try except
块中调用Terminate
。 - Niyoko