为什么存储在python3 threadlocals中的对象在线程结束之前被垃圾收集?

问题描述

我有一个可以从多个线程调用的工厂方法。该方法在线程局部变量中查找某个对象,如果它不存在,则创建一个并将其存储在线程局部变量中,然后返回相同的对象。

因此创建的对象具有用于清理的 __del__ 方法

这是一个解释我在做什么的小代码。我的期望是,工厂创建的对象只有两个,一个在主线程中,另一个在守护线程中。

import time
import threading


class MysteryObject:
    def __init__(self,name):
        self.name = name

    def __del__(self):
        print('{} => {} destroyed'.format(self.__class__.__name__,self.name))


def get_thread_ident():
    current = threading.currentThread()
    return '_'.join([current.getName(),str(current.ident)])


def make_object():
    thread_ident = get_thread_ident()
    thread_locals = threading.local()
    if hasattr(thread_locals,'mystery_object'):
        print('found mystery object in thread {}'.format(thread_ident))
        return thread_locals.mystery_object
    print('Creating mystery object in thread {}'.format(thread_ident))
    thread_locals.mystery_object = MysteryObject(thread_ident)
    return thread_locals.mystery_object


def test_threaded_object_maker(total_iteration):
    iteration = 0
    my_obj = make_object()
    while iteration < total_iteration:
        my_cur_obj = make_object()
        if id(my_cur_obj) != id(my_obj):
            print('{} Thread mystery object was GCed'.format(my_obj.name))
            my_obj = my_cur_obj
        time.sleep(2)
        iteration += 2


def test_object_maker_main():
    main_thread_mystery = make_object()
    threads = []
    for _ in range(1):
        threads.append(threading.Thread(target=test_threaded_object_maker,args=(5,)))
        threads[-1].start()
    for th in threads:
        th.join()
    main_thread_mystery2 = make_object()
    if id(main_thread_mystery) != id(main_thread_mystery2):
        print('Error main thread mystery object was GCed')


if __name__ == '__main__':
    test_object_maker_main()

但是当我运行代码时,我看到...

Creating mystery object in thread MainThread_140259104548672
Creating mystery object in thread Thread-1_140259096856320
Creating mystery object in thread Thread-1_140259096856320
Thread-1_140259096856320 Thread mystery object was GCed
MysteryObject => Thread-1_140259096856320 destroyed
Creating mystery object in thread Thread-1_140259096856320
Thread-1_140259096856320 Thread mystery object was GCed
MysteryObject => Thread-1_140259096856320 destroyed
Creating mystery object in thread Thread-1_140259096856320
Thread-1_140259096856320 Thread mystery object was GCed
MysteryObject => Thread-1_140259096856320 destroyed
MysteryObject => Thread-1_140259096856320 destroyed
Creating mystery object in thread MainThread_140259104548672
Error main thread mystery object was GCed
MysteryObject => MainThread_140259104548672 destroyed
MysteryObject => MainThread_140259104548672 destroyed

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)