4

我有多线程应用程序,当应用程序结束时我遇到了一个小问题:我可以通过调用事件处理程序中的方法正确终止线程TThread.TerminateForm1.OnDestroy但终止确实需要一些时间,所以我无法释放内存(通过TThread.Free方法)。不幸的是,由于某些其他原因,我必须将TThread.FreeOnTerminate属性设置为 false,因此线程对象不会在线程终止后自动销毁。

我的问题可能有点傻,我早就应该知道了,但是这样可以吗,线程会自动销毁(因为应用程序刚刚结束),还是有问题,内存会“丢失” ? 非常感谢您的解释。

4

5 回答 5

7

在开始关闭应用程序的其余部分之前,您应该等待线程终止,否则可能会在线程脚下释放共享资源,从而可能导致一系列访问冲突。等待线程终止后,您可以释放它。事实上,这就是TThread析构函数为你做的事情。

如果没有共享资源,那么当然,让它自己死掉。即使线程在主线程之后终止,所需要的只是所有线程都退出以使程序终止。与线程对象关联的任何内存都将被清理并与其他所有内容一起返回给操作系统。

但是,要小心!如果你的线程需要一段时间才能退出,它可能会导致一个僵尸进程坐在那里,在没有 GUI 的情况下翻腾。这就是为什么在线程循环中经常检查标志并退出线程非常重要的原因Terminated

N@

于 2010-07-09T05:47:51.423 回答
4

您的问题既不傻也不简单 - 请阅读MSDN 文章。总而言之,如果您想安全起见,最好在退出应用程序之前等待后台线程终止。

于 2010-07-09T05:07:04.377 回答
1

该线程最终将终止,Windows 将清理剩余的所有内存。但是,您不妨等待线程终止,因为这正是 Windows 无论如何都会做的事情。您的应用程序可能似乎已关闭,因为所有窗口可能已关闭/隐藏,但应用程序进程在所有线程完成之前不会终止......

于 2010-07-09T06:19:11.157 回答
0

当进程终止时,操作系统将回收所有分配的内存并关闭所有打开的句柄。您无需担心在关闭应用程序的特殊事件中泄漏的 MEMORY*)。操作系统也会关闭所有打开的句柄**),至少理论上是这样。考虑到所有这些,在终止其他共享资源之前,您可以安全地从表单析构函数中简单地终止线程(使用TerminateThread(MyThread.Handle) )。问自己这些问题:

  1. 线程在做什么?随时终止它是否安全?示例:如果线程正在对磁盘进行任何写入,那么直接杀死它是不安全的,因为您可能会在磁盘上以不一致​​的状态保存文件。
  2. 您是否正在使用 Windows 不会自动释放的任何资源?在这里想不出一个很好的例子......

如果您对两者都安全,则可以使用 TerminateThread 而不是等待线程自然终止。一种更安全的方法可能是一种组合方法,也许你应该给线程一个自然终止的机会,如果它没有在 5 秒内终止,则强制终止它。

*)我说的是内存,你只能证明进程终止时的泄漏,比如你杀死的线程没有给它们正确关闭的机会,或者你没有释放的全局单例类。所有其他下落不明的内存都需要追踪和修复,因为这是一个错误。

**) 不幸的是,Windows 操作系统并非没有错误。示例:在 Windows 平台上使用串行设备的任何人都知道将串行设备置于“锁定”状态是多么容易,需要重新启动才能使其再次工作。从技术上讲,这也是一个句柄,最终处理锁定它的应用程序应该解锁它。

于 2010-07-09T06:01:31.820 回答
0

为什么在创建线程时不增加变量,并且在销毁事件时等到线程完成,减少变量,然后在 applicationterminate 上只执行 Application.processmessages ?

为什么你的线程不是 freeonterminate=true ?所有共享资源都可以处理成一个临界区。

最好的祝福,

于 2010-07-09T07:43:12.103 回答