Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi-当应用程序退出时,未释放(但终止)线程会发生什么情况?_Delphi_Multithreading_Vcl_Delphi 6 - Fatal编程技术网

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

Delphi-当应用程序退出时,未释放(但终止)线程会发生什么情况?,delphi,multithreading,vcl,delphi-6,Delphi,Multithreading,Vcl,Delphi 6,我有一个多线程应用程序,当应用程序结束时我遇到了一个小问题:我可以通过调用TThread.terminateForm1.ondestry事件处理程序中的方法来正确终止线程,但终止确实需要一些时间,因此我无法释放内存(通过TThread.free方法)。 不幸的是,由于其他原因,我必须将TThread.FreeOnTerminate属性设置为false,这样线程终止后线程对象不会自动销毁 我的问题可能有点傻,我早就应该知道了,但这样行吗,线程会自动销毁(因为应用程序刚刚结束),还是有问题,内存会“

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


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

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

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

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

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


N@

当进程终止时,操作系统将回收所有分配的内存并关闭所有打开的句柄。您不必担心在关闭应用程序这一非常特殊的事件中会泄漏内存*)。操作系统还将关闭所有打开的句柄**),至少理论上如此。考虑到所有这些因素,在终止其他共享资源之前,您可以安全地从forms析构函数终止线程(使用)。问问自己这些问题:

  • 线在干什么?在任何时候终止它安全吗?示例:如果线程正在对磁盘执行任何写入操作,那么仅仅杀死它是不安全的,因为您可能会在磁盘上的文件处于不一致状态
  • 您是否正在使用Windows未自动释放的资源?在这里想不出一个好例子
  • 如果两者都安全,那么可以使用TerminateThread,而不必等待线程自然终止。更安全的方法可能是组合方法,也许你应该给线程一个自然终止的机会,如果它没有在5秒内终止,那么强制终止它

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


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

    线程最终将终止,Windows将清除所有剩余内存。但是,您也可以等待线程终止,因为Windows无论如何都会这样做。您的应用程序可能已关闭,因为所有窗口都已关闭/隐藏,但在所有线程完成之前,应用程序进程不会终止…

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

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


    祝您好运,

    您的代码太复杂了。自从引入
    TThread
    以来,析构函数就调用了
    Terminate
    WaitFor
    本身。一个简单的
    Free
    (或
    FreeAndNil
    )就足够了。如果线程类有一个重写的析构函数,它应该在其中调用
    Terminate
    WaitFor
    本身,因为它不能在线程过程结束之前销毁字段。将所有这些留给thread类的用户太危险了。是腰带和背带。。。我已经让程序挂起在
    TThread
    析构函数中,因为线程已经终止,并且它再次尝试终止它(等待无限长的时间等待永远不会发生的关闭),因此代码被删除。也许我一直在捕捉线程终止和正在执行的线程清理代码之间的线程。感谢您在这里发布的代码,以及mghie的评论,它帮助我解决了大部分问题。这就是他为什么要外出拍照的原因。线程第1课:不要终止线程;发信号让它停止,然后等待它完成。这是
    TThread.Terminate
    方法通过设置
    Terminated
    标志有效地完成的操作,您可以将该标志签入代码作为退出的信号。我的问题是我已重写线程析构函数,没有等待线程终止。我承认我仍然在学习使用线程,但不知何故我忽略了
    WaitFor
    方法