Delphi - 当应用程序退出时,未释放(但已终止)的线程会发生什么?

时间:2010-07-09 04:25:43

标签: delphi multithreading vcl delphi-6

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

我的问题可能有点傻了,我很久以前就应该知道了,但是这样就可以了,线程会被自动销毁(因为应用程序刚刚结束),或者它是一个问题而且内存会是“丢失”?非常感谢您的解释。

5 个答案:

答案 0 :(得分:7)

等待线程终止,然后再开始关闭应用程序的其余部分,否则共享资源可能会在线程脚下被释放,可能会导致一串访问违法行为。等待线程终止后,可以释放它。事实上,这就是TThread析构函数为您所做的事情。

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

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

N - [

答案 1 :(得分:4)

您的问题不是愚蠢或简单 - 请阅读MSDN article。总而言之,如果您想要安全起见,最好在退出应用程序之前等待后台线程终止。

答案 2 :(得分:1)

线程最终将终止,Windows将清理剩余的内存。但是,您可能只是等待线程终止,因为这正是Windows将要做的事情。您的应用程序可能出现已关闭,因为所有窗口可能已关闭/隐藏,但应用程序进程将不会终止,直到所有线程都已完成...

答案 3 :(得分:0)

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

  1. 线程在做什么?随时终止它是否安全?示例:如果线程正在对磁盘进行任何写入操作,那么将其删除是不安全的,因为您可能会在磁盘上以不一致​​的状态存活文件。
  2. 您使用的是Windows未自动释放的任何资源吗?想不出这里的好例子......
  3. 如果您对两者都安全,可以使用TerminateThread而不是等待线程自然终止。更安全的方法可能是一种组合方法,也许你应该给线程一个自然终止的机会,如果它没有终止5秒,强制终止它。

    *)我说的是内存,你可以证明只有在进程终止时泄漏,比如你杀死的线程没有给他们正确关闭的机会,或者你没有自由的全局单例类。所有其他未记录的内存需要被追踪并修复,因为这是一个错误。

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

答案 4 :(得分:0)

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

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

最好的问候,