本文介绍了蟒蛇:如果后台线程还活着,不运行weakref.finalize的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用 weakref.finalize 进行清理当对象不可见时一些后台线程,但是当对象在模块范围内时终结器未运行(edit:).

但是请注意,该对象没有对活动线程的引用,我看不出没有对其进行垃圾回收的原因.

Note however that the object own no reference to the active threads, I can see no reason for it not to be garbage collected.

显式调用del可以解决此问题,但这很不方便.

An explicit call to del solves the issue but this is inconvenient.

此处的实时演示: 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 所述,模块级对象仅在卸载模块时才收集垃圾,因此在实践中解释器退出时才收集垃圾.

As noted by @quamrana, module level objects only get garbage collected when the module is unloaded, so when the interpreter exits in practice.

不幸的是,活动线程也以refcount> 0驻留在已加载的线程模块中,这阻止了当前模块的卸载,从而阻止了对象的垃圾回收...

Unfortunately, active threads also live in the loaded threading module with a refcount > 0, which prevents the current module from being unloaded and therefore the object from being garbage collected...

所以确保对象是gc的唯一方法是确定变量的范围或确保线程自己超时.

So the only way to ensure the object is gc is to scope the variable or make sure the threads timeout by themselves.

这篇关于蟒蛇:如果后台线程还活着,不运行weakref.finalize的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-27 19:19