运行我的代码时,我启动一个运行大约50秒的线程并执行大量的后台操作。如果我运行这个程序,然后很快关闭它,那些东西仍然会在后台运行一段时间,因为线程永远不会死掉。如何在我的MianWindow类中的closeEvent方法中优雅地杀死线程?我已经尝试设置一个名为exit()的方法,在相关线程中创建一个'quitOperation'信号,然后尝试使用
myThread.quitOperation.emit()
我希望这会在我的线程中调用我的exit()函数,因为我在构造函数中有这一行:
self.quitOperation.connect(self.exit)
但是,当我使用第一行时它会断开,说'myThread'没有属性'quitOperation'。为什么是这样?还有更好的方法吗?
答案 0 :(得分:0)
我不确定python,但我认为这个myThread.quitOperation.emit()
会发出一个信号让线程退出。关键是当你的工作者正在使用线程并且没有返回时,也没有运行QCoreApplication::processEvents()
,myThread
将永远不会有机会实际处理你的请求(这称为线程饥饿)。
正确的答案可能取决于情况,以及你的线程正在做的“东西”的性质。最常见的做法是主线程向工作线程发送信号,其中槽设置标志。在阻止过程中,您会定期检查此标志。它设置你停止你正在做的任何“东西”,告诉你的工作线程它可以退出(信号最好与排队连接),在工作对象本身调用deleteLater()
,并从任何函数返回你当前在,所以线程的事件处理程序可以运行,并清除你的工作对象及其自身,最后退出。
如果你的“东西”是一个非常快速操作的巨大循环,比如简单的数学或逐个目录导航,每个只需几毫秒,这就足够了。
如果你的“东西”包含你无法控制的巨大阻塞部分(因此你不能在其中放置这个标志检查调用),你可能需要在主线程中等待直到工作线程退出。
如果您使用直接连接来设置标志,或者直接设置它,请确保使用QMutex
保护标志的读/写访问权限以防止读取不一致或用户排队连接到确保单个线程访问该标志。
虽然非常气馁,但您可以选择使用QThread
的{{1}}方法即时终止线程。你永远不应该这样做,因为它可能会导致内存泄漏,堆损坏,资源泄漏以及任何讨厌的东西,因为析构函数和清理代码将无法运行,并且可以在不希望的状态下暂停执行。