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()
Répondre
Mark avait presque droit - essentiellement "mydata" va contenir des références à toutes les variables de TL en elle, quel que soit fil ils ont été créés de. À savoir ...:
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!"
Emet:
t created
t started
x got deleted!
mydata deleted
t joined
Done!
gc joue effectivement aucun rôle dans CPython, de sorte que vous pouvez simplifier le code jusqu'à:
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!"
et encore voir ...:
t created
x got created!
t started
x got deleted!
mydata deleted
t joined
Done!
En faisant un couple de simples changements à votre programme et en forçant une collecte des ordures après chaque étape du filetage, il semble que foo
ne peuvent être collectées jusqu'à ce que le programme soit terminé - autrement dit, après le fil sort de portée.
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!"
sortie (en utilisant Python 2.6, Windows):
>C:\temp\py\t.py t created t started t joined Done! x got deleted!
Merci! Il semble que le programme de Mark se comporte différemment dans CPython 2.5 et 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!"
Emet (sous 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!
Et:
Python 2.6.2 (r262:71600 Sep 19 2009 17:24:20)
t created
t started
x got deleted!
mydata deleted
t joined
Done!
Voici ma réponse, puisque Je ne parviens pas à voir la conclusion dans les réponses précédentes. J'ai commencé à me poser la même question et j'ai essayé un programme de test similaire à ceux des autres réponses, et je suis arrivé à la conclusion que les tests sont effectués plus tôt que la fin du programme, ce qui signifie que ces références peuvent être déterminées déchets une fois le fil meurt lui-même.
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 sortie:
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
Comme vous pouvez le voir, la supprimer de semblent se produire dès que le fil meurt.
- 1. Quelle est la durée de vie des données?
- 2. Durée de vie de la connexion SQL
- 3. Durée de vie de la connexion TCP
- 4. Quelle est la durée de vie d'une classe statique affectée dans une application asp.net sans état?
- 5. Quelle est la durée de vie d'une variable dans un programme (en Java)?
- 6. Quelle est la valeur de la priorité du thread principal?
- 7. Quelle est la durée de vie et la validité des itérateurs C++?
- 8. WCF variable durée de vie/état
- 9. PHP: Quelle est la durée de vie par défaut d'une session
- 10. Comportement de service WCF Durée de vie
- 11. .NET CF Running Thread pour la durée de vie d'une application
- 12. Suivi de la durée de vie variable automatique?
- 13. Qu'est-ce que la durée de vie maximale d'un segment
- 14. Linq to SQL dataContext problème de durée de vie
- 15. En Python, quelle est la meilleure façon d'exécuter une commande Linux locale stockée dans une chaîne?
- 16. Quelle est la syntaxe de liaison de valeur dans xaml?
- 17. Comment gérer un "thread" de longue durée dans WPF?
- 18. Durée de vie des messages dans une file d'attente de messages
- 19. Quelle est la valeur de OPEN_EXISTING dans l'API Windows?
- 20. python quitte un thread de blocage?
- 21. EF ObjectContext, Service and Repository - Gestion de la durée de vie du contexte.
- 22. Connexion sqlite3 et stockage pendant la durée de vie de l'application
- 23. Définir la durée de vie maximale de l'entité dans le bloc de cache de la bibliothèque Enterprise?
- 24. Quelle est la différence entre un thread de travail et un thread d'E/S?
- 25. Variable de service Web partagée pour la durée de vie du service Web?
- 26. Quelle syntaxe est la meilleure pour la valeur de retour?
- 27. Calcul de la durée de la vidéo
- 28. Quelle est la raison d'avoir '//' en Python?
- 29. Quelle est la meilleure façon de rechercher une valeur de dictionnaire Python dans une liste de dictionnaires?
- 30. Est-il correct de supposer que la valeur initiale d'une variable locale est zéro?
Bonne analyse, mais le bit manquant est que _mydata_ s'en va est ce que vous avez besoin - J'ai besoin d'ouvrir une nouvelle réponse pour afficher le code formaté, mais l'essentiel est le même que le vôtre. –