尝试优雅地停止QThread,这个实现有什么问题?

2024-10-03 04:36:40 发布

您现在位置:Python中文网/ 问答频道 /正文

当运行我的代码时,我会启动一个线程,该线程运行大约50秒,并执行很多后台工作。如果我运行这个程序,然后很快关闭它,这些东西仍然会在后台运行一段时间,因为线程永远不会死。如何在主窗口类的closeEvent方法中优雅地终止线程?我尝试设置一个名为exit()的方法,在相关线程中创建一个信号“quitOperation”,然后尝试使用

myThread.quitOperation.emit()

我希望这会在我的线程中调用exit()函数,因为我的构造函数中有一行:

^{pr2}$

但是,当我使用第一行时,它就断了,说“myThread”没有属性“quitOperation”。为什么会这样?有更好的方法吗?在


Tags: 方法函数代码程序属性信号exit线程
1条回答
网友
1楼 · 发布于 2024-10-03 04:36:40

我不确定python,但我假设这个myThread.quitOperation.emit()发出一个信号,让线程退出。关键是,当您的工作线程正在使用并且不返回,也不运行QCoreApplication::processEvents()myThread将永远没有机会实际处理您的请求(这称为线程饥饿)。在

正确的答案可能取决于具体情况,以及你的线程正在执行的“任务”的性质。最常见的做法是主线程向工作线程发送一个信号,其中槽设置一个标志。在阻塞过程中,您定期检查此标志。如果设置为停止您正在做的任何“工作”,告诉您的工作线程它可以退出(最好使用排队连接的信号),对工作对象本身调用deleteLater(),并从当前使用的任何函数返回,以便线程的事件处理程序可以运行,并清除工作对象和自身,最后退出。在

如果你的“资料”是一个巨大的周期,非常快的操作,如简单的数学或目录导航,一个一个只需要几毫秒,这就足够了。在

如果你的“东西”包含你无法控制的巨大阻塞部分(因此你不能在其中放置这个标志检查调用),你可能需要在主线程中等待,直到工作线程退出。在

如果您使用direct connect来设置标志,或者您直接设置它,请确保使用QMutex来保护对该标志的读/写访问,以防止不一致的读取,或者使用排队连接来确保该标志的单线程访问。在

尽管极力劝阻,您也可以选择使用QThreadterminate()方法来立即终止线程。千万不要这样做,因为它可能会导致内存泄漏、堆损坏、资源泄漏和任何讨厌的事情,因为析构函数和清理代码将无法运行,并且执行可能会在不希望的状态下停止。在

相关问题 更多 >