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

Terminating Qt worker thread during program shutdown

我使用 Qt 4.8.6,MS Visual Studio 2008,Windows 7. 我创建了一个 GUI 程序。它包含主 GUI 线程和工作线程(顺便说一下,我没有制作 QThread subclass),它们同步调用第 3 方 DLL 函数。这些功能相当慢。 QTcpServer 实例也在工作线程下。我的工人 class 包含 QTcpServer 和 DLL 包装器方法。

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

QThread::quit 告诉线程的事件循环退出。调用它后,线程将在控制 returns 到线程的事件循环

后立即完成

您也可以通过 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();

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

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

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

除非有压倒一切的理由,否则您不应尝试在进程终止时使用用户代码终止线程。

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

尝试使用用户代码 'clean up' 听起来 'nice',(显然),但这是一种昂贵的奢侈品,您将支付额外的代码、额外的测试和额外的维护费用。

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

OS 非常擅长停止线程和清理。它在开发过程中进行了数千小时的测试,并在野外使用了数十年,在这些环境中,进程终止问题会变得很明显并得到修复。当您在没有处理器间驱动程序的情况下努力停止另一个内核上的线程 运行 时,您甚至无法通过标志、事件等接近它。

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

如果不是,请不要尝试以 'niceness' 的名义复制 OS 功能。只要求它终止你的进程。当您的应用程序立即关闭而其他开发人员仍在努力实现 'Shutdown' 进度条或试图向客户解释为什么他们仍然有 15 个僵尸应用程序时,您可能会感到温暖、模糊 运行.