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()
Respuesta
Mark tenía casi la derecha - esencialmente "misdatos" puede contener referencias a todas las variables TL en el mismo, cualquiera que sea el hilo que fueron creados de. A saber ...:
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!"
Emite:
t created
t started
x got deleted!
mydata deleted
t joined
Done!
gc realidad no juega ningún papel aquí en CPython, por lo que puede simplificar el código a:
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!"
sin dejar de ver ...:
t created
x got created!
t started
x got deleted!
mydata deleted
t joined
Done!
Al hacer un par de cambios simples en su programa y obligando a una recolección de basura después de cada paso de la rosca, parece que foo
no se pueden recoger hasta que el programa ha terminado - en otras palabras, después el hilo se apaga de alcance
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()
t.join()
print "t joined"
gc.collect()
print "Done!"
salida (usando Python 2.6, Windows):
>C:\temp\py\t.py t created t started t joined Done! x got deleted!
Gracias! Parece que el programa de Mark se comporta de manera diferente bajo CPython 2.5 y 2.6:
import threading
import gc
import platform
print "Python %s (%s)" % (platform.python_version(), " ".join(platform.python_build()))
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!"
Se emite (bajo Ubuntu 8.04 i386):
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!
Y:
Python 2.6.2 (r262:71600 Sep 19 2009 17:24:20)
t created
t started
x got deleted!
mydata deleted
t joined
Done!
aquí está mi respuesta, ya No veo la conclusión en las respuestas anteriores.
Empecé a preguntarme lo mismo y probé un programa de prueba que es similar a los de otras respuestas y mi conclusión fue que sí reciben GCed antes que el final del programa, lo que significa que estas referencias se pueden determinar como basura una vez que el hilo muere.
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)
La salida:
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
Como se puede ver, la eliminación de parecen ocurrir tan pronto como el hilo muere.
- 1. ¿Cuál es la duración de un valor memorable en un lenguaje funcional como Haskell?
- 2. Cuál es la duración de un Toast LENGTH_LONG y LENGTH_SHORT
- 3. Java Grupo de subprocesos en caché y subprocesos local
- 4. ¿Cuál es la duración de una llamada de Ajax?
- 5. ¿Cuál es el valor de retorno de Socket.accept() en Python
- 6. PHP: ¿Cuál es la duración predeterminada de una sesión
- 7. ¿Cuál es la duración óptima para la contraseña del usuario?
- 8. ¿Cuál es el valor lógico de "cadena" en Python?
- 9. ¿Qué es "almacenamiento local de subprocesos" en Python, y por qué lo necesito?
- 10. ¿Cuál es la duración de un argumento predeterminado vinculado temporalmente a un parámetro de referencia?
- 11. Cómo inicializar la variable local de subprocesos en C++?
- 12. ¿Cuál es el significado de "Grupo de subprocesos" en JMeter?
- 13. variables estáticas, ¿cuál es su duración de vida?
- 14. Uso de la memoria de almacenamiento local de subprocesos
- 15. En Python, ¿cuál es la mejor manera de ejecutar un comando local de Linux almacenado en una cadena?
- 16. ¿Cuál es la mejor forma de obtener una duración de archivo de audio en Android?
- 17. ¿Cuál es la mejor forma de comunicarse entre un servicio WCF y subprocesos separados?
- 18. Cuál es la mejor manera de almacenar la duración en MySQL
- 19. ¿Cuál es la forma "correcta" de pasar un valor booleano a una extensión Python C?
- 20. Uso de un diccionario global con subprocesos en Python
- 21. Perfilado de subprocesos de Python
- 22. ¿Cuál es el valor máximo de un número en Lua?
- 23. Descarga de subprocesos de Python
- 24. ¿Cuál es la duración óptima de un rastreador web para esperar entre solicitudes repetidas a un servidor web?
- 25. Lectura de un único archivo de varios subprocesos en python
- 26. ¿Cuál es la mejor práctica para manejar tuplas de valor único en Python?
- 27. ¿Multiprocesamiento.Pool de Python admite subprocesos remotos?
- 28. ¿Cuál es la forma más simple de usar SSH Python?
- 29. ¿Cuál es la mejor manera de buscar un valor de diccionario de Python en una lista de diccionarios?
- 30. Duración de los argumentos de la función Python?
Buen análisis, pero lo que falta es que _mydata_ va a desaparecer es lo que necesita - Necesito abrir una nueva respuesta para mostrar el código formateado, pero la esencia es muy similar a la suya. –