python:如果后台线程处于活动状态,则不会运行weakref.finalize
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python:如果后台线程处于活动状态,则不会运行weakref.finalize相关的知识,希望对你有一定的参考价值。
当对象不在视线范围内时,我想使用weakref.finalize
清理一些后台线程,但当对象在模块范围内时,终结器不会运行(编辑:)。
但请注意,该对象没有引用活动线程,我看不出它是不被垃圾收集的原因。
对del
的明确调用解决了这个问题,但这很不方便。
现场演示:https://ideone.com/kTZsbs
import weakref
import threading
def do(l):
l.acquire()
class A:
def __init__(self):
l = threading.Lock()
l.acquire()
t = threading.Thread(target=do, args=[l])
t.start()
weakref.finalize(self, A._finalize, t, l)
@staticmethod
def _finalize(t, l):
print("finalizing")
l.release()
t.join()
a = A()
# del a does trigger _finalize though
答案
正如@quamrana所指出的,模块级对象只在卸载模块时才收集垃圾,因此当解释器在实践中退出时。
不幸的是,活动线程也存在于加载的线程模块中,引用计数> 0,这会阻止当前模块被卸载,因此对象不会被垃圾收集......
因此,确保对象是gc的唯一方法是对变量进行范围调整或确保线程自行超时。
另一答案
你只需要一种让a
超出范围的方法:
def main():
a = A()
# when main exits, a will be garbage collected
main()
输出:
finalizing
以上是关于python:如果后台线程处于活动状态,则不会运行weakref.finalize的主要内容,如果未能解决你的问题,请参考以下文章
我需要在使用 Firebase 收到通知(应用程序处于打开、后台、活动状态)后调用 API