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

时间:2015-04-01 06:58:52

标签: c++ multithreading qt synchronous application-shutdown

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

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

3 个答案:

答案 0 :(得分:2)

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();

答案 1 :(得分:0)

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

当一个线程被要求自行终止时,它会完成正在进行的操作并且干净利落地存在。应用程序等待线程终止然后退出。

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

答案 2 :(得分:-1)

除非有最重要的理由这样做,否则您不应尝试在进程终止时使用用户代码终止线程。

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

尝试使用用户代码“清理”听起来“不错”,(很明显),但这是一种昂贵的奢侈品,您将通过额外的代码,额外的测试和额外的维护来支付费用。

也就是说,如果您的客户没有停止购买您的应用,因为他们很生气,需要很长时间才能关闭。

操作系统非常擅长阻止线程和清理。它在开发期间和在野外数十年的生命中进行了数千小时的测试,其中过程终止的问题将变得无法解决并得到修复。在没有处理器间驱动程序的情况下,你很难用你的旗帜,事件等来接近它,因为你很难阻止线程在另一个核心上运行。

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

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