1

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

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

4

3 回答 3

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();
于 2015-04-01T08:17:11.860 回答
0

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

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

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

于 2015-04-01T08:19:13.193 回答
-1

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

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

尝试用用户代码“清理”听起来很“不错”,(显然),但这是一种昂贵的奢侈品,你需要为额外的代码、额外的测试和额外的维护付出代价。

也就是说,如果您的客户不停止购买您的应用程序,因为他们对关闭时间太长感到恼火。

操作系统非常擅长停止线程和清理。它在开发过程中进行了数千小时的无休止的测试,并在野外生活了数十年,其中流程终止的问题将变得明显并得到修复。在没有处理器间驱动程序的好处的情况下,您甚至无法通过标志、事件等来接近它,因为您很难停止在另一个内核上运行的线程。

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

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

于 2015-04-01T11:37:22.750 回答