什么';在Python中,线程本地值的生命周期是多少?
通过对程序进行一些简单的更改,并在线程的每个步骤之后强制执行垃圾收集,在程序完成之前,即线程超出范围之后,什么';在Python中,线程本地值的生命周期是多少?,python,multithreading,Python,Multithreading,通过对程序进行一些简单的更改,并在线程的每个步骤之后强制执行垃圾收集,在程序完成之前,即线程超出范围之后,foo似乎无法收集 import threading mydata = threading.local() def run(): # When will the garbage collector be able to destroy the object created # here? After the thread exits from ``run()``? Aft
foo
似乎无法收集
import threading
mydata = threading.local()
def run():
# When will the garbage collector be able to destroy the object created
# here? After the thread exits from ``run()``? After ``join()`` is called?
# Or will it survive the thread in which it was created, and live until
# ``mydata`` is garbage-collected?
mydata.foo = object()
t = threading.Thread(target=run)
t.start()
t.join()
输出(使用Python 2.6和Windows):
>C:\temp\py\t.py
t创造
t开始
t加入
完成!
x被删除了!
马克几乎是对的——本质上,“mydata”将包含对其中所有TL变量的引用,不管它们是从哪个线程创建的。也就是说
>C:\temp\py\t.py
t created
t started
t joined
Done!
x got deleted!
发射:
import threading
import gc
mydata = threading.local()
class x:
def __del__(self):
print "x got deleted!"
def run():
mydata.foo = x()
t = threading.Thread(target=run)
print "t created"
gc.collect()
t.start()
print "t started"
gc.collect()
del mydata
print "mydata deleted"
gc.collect()
t.join()
print "t joined"
gc.collect()
print "Done!"
gc实际上在CPython中不起任何作用,因此您可以将代码简化为:
t created
t started
x got deleted!
mydata deleted
t joined
Done!
但你仍然看到
import threading
mydata = threading.local()
class x:
def __init__(self):
print "x got created!"
def __del__(self):
print "x got deleted!"
def run():
mydata.foo = x()
t = threading.Thread(target=run)
print "t created"
t.start()
print "t started"
del mydata
print "mydata deleted"
t.join()
print "t joined"
print "Done!"
谢谢!似乎Mark的程序在CPython 2.5和2.6下的表现有所不同:
t created
x got created!
t started
x got deleted!
mydata deleted
t joined
Done!
Emits(在Ubuntu 8.04 i386下):
以及:
这是我的答案,因为我没有看到前面答案中的结论 我开始思考同样的问题,并尝试了一个与其他答案中的测试程序类似的测试程序,我的结论是,它们在程序结束之前得到GCed,这意味着,一旦线程本身死亡,这些引用就可以被确定为垃圾
Python 2.6.2 (r262:71600 Sep 19 2009 17:24:20)
t created
t started
x got deleted!
mydata deleted
t joined
Done!
输出:
import time
import threading
import gc
data = threading.local()
class Resource(object):
def __init__(self):
self.name = threading.currentThread().name
print 'create: %s' % self.name
def __del__(self):
print 'delete: %s' % self.name
def access_thlocal():
data.key = Resource()
for i in range(0, 10):
threading.Thread(target=access_thlocal).start()
time.sleep(1)
print "Triggering GC"
gc.collect()
time.sleep(1)
正如您所看到的,删除似乎会在线程死后立即发生。分析得很好,但缺少的一点是mydata的消失正是您所需要的--我需要打开一个新的答案来显示格式化代码,但要点与您的大致相同。这似乎仍然是CPython 3.6中的当前行为。
Python 2.5.2 (r252:60911 Jul 31 2008 19:40:22)
t created
t started
mydata deleted
x got deleted!
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python2.5/threading.py", line 486, in __bootstrap_inner
self.run()
File "/usr/lib/python2.5/threading.py", line 446, in run
self.__target(*self.__args, **self.__kwargs)
File "./x.py", line 14, in run
mydata.foo = x()
NameError: global name 'mydata' is not defined
t joined
Done!
Python 2.6.2 (r262:71600 Sep 19 2009 17:24:20)
t created
t started
x got deleted!
mydata deleted
t joined
Done!
import time
import threading
import gc
data = threading.local()
class Resource(object):
def __init__(self):
self.name = threading.currentThread().name
print 'create: %s' % self.name
def __del__(self):
print 'delete: %s' % self.name
def access_thlocal():
data.key = Resource()
for i in range(0, 10):
threading.Thread(target=access_thlocal).start()
time.sleep(1)
print "Triggering GC"
gc.collect()
time.sleep(1)
create: Thread-1
create: Thread-2
delete: Thread-1
create: Thread-3
delete: Thread-2
create: Thread-4
delete: Thread-3
create: Thread-5
delete: Thread-4
create: Thread-6
delete: Thread-5
create: Thread-7
delete: Thread-6
create: Thread-8
delete: Thread-7
create: Thread-9
delete: Thread-8
create: Thread-10
delete: Thread-9
Triggering GC
delete: Thread-10