什么是threading.current_thread()中的虚拟对象?

时间:2019-04-20 22:41:58

标签: python multithreading pyqt python-multithreading qthread

我正在尝试理解此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)时看到了类似的输出。

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

1 个答案:

答案 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的影响,因为它们存储在字典中,因此不会造成内存泄漏。