首页 > 解决方案 > threading.current_thread() 中的 Dummy 是什么?

问题描述

我试图理解如何在 pyqt 中使用 moveToThread() 正确使用 QThread 中的代码?

具有的部分:

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元素到底是什么,我的理解是这些是工作线程,但它们会永远“活着”吗?或者他们会自己被垃圾收集。如果添加批次完成 10k 次,代码输出是否会有 10k Dummy-1项?我之所以问,是因为我在使用子类 Qthreads 时看到了类似的输出(在调试模式下运行代码时在 Eclispe 中使用 Pydev)。

我不确定这是否意味着某种泄漏(线程泄漏)最终会消耗大量资源。

标签: pythonmultithreadingpyqtpython-multithreadingqthread

解决方案


QThread 不是Qt 的线程,而是用于处理每个操作系统的本机线程的类,python 的线程模块如何,这在文档中有所提及:

QThread 类提供了一种独立于平台的方式来管理线程。

因此,当使用threading.current_thread()python 尝试获取本机线程但正如文档指出的那样(您也可以在源代码中看到它):

返回当前的 Thread 对象,对应于调用者的控制线程。如果调用者的控制线程不是通过线程模块创建的,则返回一个功能有限的虚拟线程对象。

因为 QThread 创建了一个未被线程模块处理的线程,这将返回一个代表该线程的虚拟线程。

这些存储在线程模块内的字典中,因此它们不会被 GC 删除并且它们不是泄漏。这在文档中提到:

有可能会创建“虚拟线程对象”。这些是对应于“外来线程”的线程对象,它们是在线程模块之外启动的控制线程,例如直接从 C 代码。虚拟线程对象的功能有限;它们总是被认为是活着的和守护进程的,并且不能被 join()ed。它们永远不会被删除,因为无法检测到外来线程的终止。

源代码中:

# 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 影响,因为它们存储在字典中,因此不是内存泄漏。


推荐阅读