我有多线程应用程序,当应用程序结束时我遇到了一些问题:我可以通过在TThread.Terminate
事件处理程序中调用Form1.OnDestroy
方法来正确终止线程,但终止确实需要一些时间所以我无法释放内存(通过TThread.Free
方法)。
不幸的是,由于某些其他原因,我必须将TThread.FreeOnTerminate
属性设置为false,因此线程终止后线程对象不会自动销毁。
我的问题可能有点傻了,我很久以前就应该知道了,但是这样就可以了,线程会被自动销毁(因为应用程序刚刚结束),或者它是一个问题而且内存会是“丢失”?非常感谢您的解释。
答案 0 :(得分:7)
你应等待线程终止,然后再开始关闭应用程序的其余部分,否则共享资源可能会在线程脚下被释放,可能会导致一串访问违法行为。等待线程终止后,可以释放它。事实上,这就是TThread
析构函数为您所做的事情。
如果没有共享资源,那么确定,让它自己死掉。即使线程在主线程之后终止,所需的只是所有线程退出以使程序终止。与线程对象关联的任何内存都将被清除,并与其他所有内容一起返回给操作系统。
但,小心!如果您的线程需要一段时间才能退出,那么可能会导致僵尸进程在没有GUI的情况下在那里停留。这就是在线程循环中经常检查Terminated
标志非常非常重要的原因,并退出线程。
N - [
答案 1 :(得分:4)
您的问题不是愚蠢或简单 - 请阅读MSDN article。总而言之,如果您想要安全起见,最好在退出应用程序之前等待后台线程终止。
答案 2 :(得分:1)
线程最终将终止,Windows将清理剩余的内存。但是,您可能只是等待线程终止,因为这正是Windows将要做的事情。您的应用程序可能出现已关闭,因为所有窗口可能已关闭/隐藏,但应用程序进程将不会终止,直到所有线程都已完成...
答案 3 :(得分:0)
当进程终止时,操作系统将回收所有已分配的内存并关闭所有打开的句柄。在关闭应用程序的特殊事件中,您无需担心MEMORY *)泄漏。操作系统也将关闭所有打开的句柄**),至少在理论上。考虑到所有这些,在杀死其他共享资源之前,从表单析构函数中简单地终止线程(使用TerminateThread(MyThread.Handle))可能是安全的。问自己这些问题:
如果您对两者都安全,可以使用TerminateThread而不是等待线程自然终止。更安全的方法可能是一种组合方法,也许你应该给线程一个自然终止的机会,如果它没有终止5秒,强制终止它。
*)我说的是内存,你可以证明只有在进程终止时泄漏,比如你杀死的线程没有给他们正确关闭的机会,或者你没有自由的全局单例类。所有其他未记录的内存需要被追踪并修复,因为这是一个错误。
**)不幸的是Windows操作系统没有错误。示例:在Windows平台上使用串行设备的任何人都知道将串行设备置于“锁定”状态是多么容易,需要重新启动才能使其再次运行。从技术上讲,这也是一个句柄,对锁定它的应用程序进行最终处理应解锁它。
答案 4 :(得分:0)
为什么你在创建线程时不增加变量,在destroy事件上等到线程完成,减少变量,在applicationterminate上只执行Application.processmessages?
为什么你的线程不是freeonterminate = true?所有共享资源都可以处理成一个关键部分。
最好的问候,