我正在尝试理解此How to use QThread correctly in pyqt with moveToThread()?
中的代码具有以下内容的部分
mainwin.__init__ : MainThread, 140221684574016,
GenericWorker.__init__ : MainThread, 140221684574016,
GenericWorker.run : Dummy-1, 140221265458944,
mainwin.addBatch : Dummy-1, 140221265458944,
mainwin.add : Dummy-1, 140221265458944,
mainwin.add : Dummy-1, 140221265458944,
mainwin.add : Dummy-1, 140221265458944,
mainwin.add : Dummy-1, 140221265458944,
mainwin.add : Dummy-1, 140221265458944,
mainwin.add : Dummy-1, 140221265458944
对我来说很有趣, Dummy -1 元素到底是什么,我的理解是,这些是执行工作的工作线程,但是它们将永远保持“活跃”状态吗?还是会自己收集垃圾。如果添加批处理完成了1万次,那么代码输出中是否会有1万个 Dummy-1 项目? 我只问是因为使用子类化的Qthreads(在调试模式下运行代码时在Eclispe中使用Pydev)时看到了类似的输出。
我不确定这是否意味着某种泄漏(线程泄漏)最终会消耗大量资源。
答案 0 :(得分:0)
QThread不是Qt的线程,而是一个用于处理每个操作系统的本机线程的类,Python的线程模块如何处理,这在{{3 }}:
QThread类提供了一种独立于平台的方式来管理线程。
因此,在使用threading.current_thread()
时,python会尝试获取本机线程,但正如docs指出的那样(您也可以在docs中看到它):
返回与调用者的线程相对应的当前Thread对象 控制。如果呼叫者的控制线程不是通过以下方式创建的 线程模块,功能有限的虚拟线程对象 返回。
由于QThread创建了线程模块未处理的线程,因此将返回代表该线程的虚拟线程。
这些内容存储在线程模块内的字典中,因此不会被GC删除,也不会泄漏。 source code中提到了这一点:
可能会创建“虚拟线程对象”。这些是与“外来线程”相对应的线程对象,“外来线程”是在线程模块外部启动的控制线程,例如直接从C代码启动的线程。虚拟线程对象的功能有限。它们始终被认为是活动的和守护程序的,并且不能被join()ed。它们永远不会被删除,因为不可能检测到外来线程的终止。
在docs中:
# Dummy thread class to represent threads not started here. # These aren't garbage collected when they die, nor can they be waited for. # If they invoke anything in threading.py that calls current_thread(), they # leave an entry in the _active dict forever after. # Their purpose is to return *something* from current_thread(). # They are marked as daemon threads so we won't wait for them # when we exit (conform previous semantics).
因此,总而言之,虚拟元素提供了有关非线程处理的线程的信息,这些元素不受GC的影响,因为它们存储在字典中,因此不会造成内存泄漏。