C++ 退出进程时等待线程完成

C++ 退出进程时等待线程完成,c++,multithreading,qt,C++,Multithreading,Qt,对于一个相当简单的问题,没有找到直接和令人满意的答案: 如果有多个线程在运行,是否有一种通用/正确的方法在退出进程时等待它们完成?或者“在这种情况下,执行定时等待是否正常?” 是的,我们试图向线程发出完成的信号,但可以观察到,在进程退出期间,其中一些线程往往会停止。我们最近进行了一次讨论,决定取消“任意等待”: 我知道kWaitMs常数的选择应该与线程完成的一个不间断的“工作周期”成一定比例。比方说,如果线程处理某个数据块10毫秒,那么我们可能应该等待它响应退出信号100毫秒,如果它仍然没有退出

对于一个相当简单的问题,没有找到直接和令人满意的答案:

如果有多个线程在运行,是否有一种通用/正确的方法在退出进程时等待它们完成?或者“在这种情况下,执行定时等待是否正常?”

是的,我们试图向线程发出完成的信号,但可以观察到,在进程退出期间,其中一些线程往往会停止。我们最近进行了一次讨论,决定取消“任意等待”:

我知道kWaitMs常数的选择应该与线程完成的一个不间断的“工作周期”成一定比例。比方说,如果线程处理某个数据块10毫秒,那么我们可能应该等待它响应退出信号100毫秒,如果它仍然没有退出,那么我们就不再等待了。在这种情况下,我们不会等待,只要我们退出计划,不再关心。但一些工程师不理解这样的“范式”,希望最终等待。请注意,在我们的例子中,程序进程卡在客户机的内存中会导致下一次程序启动时出现问题,当然,不要提及日志将不会正确完成以作为错误进行处理

是否可以回答有关在进程退出时正确完成线程的问题

Qt/API是否提供了一些帮助来更好地解决线程挂起问题,以便我们记录挂起的原因

请注意,我想知道为什么强行终止线程是错误的,以及如何才能做到这一点。我想这个问题不是关于同步,而是关于运行大量的框架和操作系统代码的线程的有限确定性。操作系统不是实时的,对吧:Windows/MacOS/Linux等等

p.p.S.所有有问题的线程都有事件循环,因此它们应该响应
QThread::quit()

是的,我们试图向线程发出完成的信号,但观察到 在退出过程中,其中一些可能会失速

这才是你真正的问题。您需要找出某些线程暂停的原因,并对其进行修复,以便它们不会暂停,并且在应该停止时总是可靠地退出。(他们退出的确切时间并不重要,只要他们在合理的时间内退出,即在用户厌倦等待并强制退出整个应用程序之前)

如果你没有/不能做到这一点,那么就没有办法可靠地关闭你的应用程序,因为你无法安全地释放线程可能仍在访问的任何资源。在主线程调用线程使用的任何对象(例如,与线程关联的QThread对象)的析构函数之前,必须100%保证线程已退出


总之:不要玩等待超时或强制终止线程的游戏;所有这些都会让你的应用程序在关机时崩溃。使用无限期等待,并确保线程总是(总是!)在主线程要求它们退出后退出,因为这是实现可靠关闭序列的唯一方法。

那么,您是否在问如何确保线程正确响应“退出”事件?或者,您是在问如何确定线程没有正确退出的原因?我不太明白你所说的“有限决定论”是什么意思。你的意思是“确保它不能运行很长时间”?主要问题是:在这种情况下,定时等待可以吗?所有相关的讨论,包括为什么它不退出的诊断。顺便说一句,当你遇到一个线程在关闭序列中暂停时,最好使用调试器或苹果活动监视器的“示例进程”功能找出线程的当前执行点在哪里(即,它被卡住的位置的堆栈跟踪)。一旦你知道线程被卡住的位置,你就可以很好地找到它被卡住的原因,以及如何解开它。我不能同意你找到这种问题的原因,但当它发生在“现场”时这有点太晚了。也许让调试代码在无限期等待发布代码的同时不关注“到期”期是有意义的。同意,“现场”太晚了——这意味着问题需要在“场外”复制并在那之前修复,如果可能的话。
m_thread.quit();          // the way we had threads finished
m_thread.wait(kWaitMs);   // with some significant expiration (~1000ms)

m_thread.quit();          // the way we have threads finished now
m_thread.wait();          // wait forever until finished