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的主要内容,如果未能解决你的问题,请参考以下文章

进度对话框和后台线程处于活动状态时如何处理屏幕方向更改?

如果当前处于活动状态,则 OpenGL 纹理不会渲染

我需要在使用 Firebase 收到通知(应用程序处于打开、后台、活动状态)后调用 API

yield函数 ,interrupt函数

iOS 8 Beta 6 - 当应用程序处于后台时处理 UILocalNotification

检测应用程序处于后台/非活动状态时是不是触发了本地通知