在程序关闭期间终止Qt工作线程

Terminating Qt worker thread during program shutdown

本文关键字:终止 Qt 工作 线程 程序      更新时间:2023-10-16

我使用Qt 4.8.6、MS Visual Studio 2008、Windows 7。我已经创建了一个GUI程序。它包含主GUI线程和工作线程(顺便说一句,我还没有创建QThread子类),它们对第三方DLL函数进行同步调用。这些功能相当缓慢。QTcpServer实例也在工作线程下。我的worker类包含QTcpServer和DLL包装器方法。

我知道quit()terminate()更受欢迎,但我不想在程序关闭期间等待一分钟(因为DLL函数很慢)。当我尝试terminate()工作线程时,我注意到关于从另一个线程停止QTcpServer的警告。流程关闭的正确方式是什么?

QThread::quit告诉线程的事件循环退出。调用它之后,一旦控件返回到线程的事件循环,线程就会完成

您也可以通过QThread::terminate()强制线程立即终止,但这是一种非常糟糕的做法,因为它可能会在代码中未定义的位置终止线程,这意味着您可能最终会遇到资源永远无法释放和其他令人讨厌的事情。所以只有当你真的无法绕过它时才使用这个。

所以我认为正确的方法是首先告诉线程正常退出,如果出现问题需要很长时间,而你没有办法等待,那么终止它:

QThread * th = myWorkerObject->thread();
th->quit();
th->wait(5000); // Wait for some seconds to quit
if(th->isRunning()) // Something took time more than usual, I have to terminate it
    th->terminate();

您应该尽量避免从外部强行杀死线程,而是友好地要求他们完成正在做的事情。这通常意味着线程定期检查它是否应该终止自己,外部世界告诉它在需要时终止(通过设置标志、发出事件信号或任何适合当前情况的方式)。

当一个线程被要求终止它自己时,它完成了它正在做的事情,并且干净地存在。应用程序等待线程终止,然后退出。

你说在你的情况下,线程需要很长时间才能完成。你可以考虑到这一点,仍然以"好的方式"终止线程(例如,你可以隐藏应用程序窗口,给人一种应用程序已经退出的印象,即使这个过程需要一点时间才能最终终止;或者你可以向用户显示某种形式的进度指示,告诉他应用程序正在关闭)。

除非有压倒一切的原因,否则不应试图在进程终止时使用用户代码终止线程。

如果没有这样的原因,只需调用操作系统进程终止系统调用,例如ExitProcess(0)。在释放所有进程资源之前,操作系统可以并且将停止任何状态下的所有进程线程。用户代码不能做到这一点,除非绝对必要,否则不应该尝试终止线程或向它们发出自终止信号。

尝试用用户代码"清理"听起来很"好",(目前),但这是一种昂贵的奢侈,你需要付出额外的代码、额外的测试和额外的维护。

也就是说,如果你的客户不停止购买你的应用程序,因为他们对花了这么长时间才关闭感到愤怒。

操作系统非常擅长停止线程和清理。在开发过程中,它经历了数千小时的无休止的测试,在野外生活了几十年,过程终止的问题会成为一个问题并得到解决。在没有进程间驱动程序的情况下,当你努力阻止线程在另一个核心上运行时,你甚至无法通过你的标志、事件等来接近这一点。

当然,有时您将不得不求助于用户代码来停止线程。如果您需要在进程终止前停止它们,或者您需要关闭一些DB连接、在关闭时刷新一些文件、处理进程间通信或类似问题,那么您将不得不采用其他答案中已经建议的一些方法。

如果没有,不要试图以"精细"的名义复制操作系统的功能。只需要求它终止您的流程。当你的应用程序立即关闭,而其他开发人员仍在努力实现"关闭"进度条或试图向客户解释为什么他们有15个僵尸应用程序仍在运行时,你会有一种温暖而模糊的感觉。