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()
Antwort
Mark hatte es fast richtig - im Wesentlichen "mydata" werden Verweise auf alle TL Variablen in sie halten, was sie geschaffen wurden Faden von. Nämlich ...:
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!"
Emits:
t created
t started
x got deleted!
mydata deleted
t joined
Done!
gc spielt eigentlich keine Rolle in CPython, so dass Sie den Code vereinfachen kann bis auf:
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!"
und noch sehen ...:
t created
x got created!
t started
x got deleted!
mydata deleted
t joined
Done!
ein paar einfache Änderungen an Ihrem Programm Indem und zwingt eine Garbage Collection nach jedem Schritt des Gewindes, so scheint es, dass foo
nicht, bis das Programm beendet ist gesammelt werden - mit anderen Worten, nach der Faden geht von Umfang.
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!"
Ausgang (mit Python 2.6, Windows):
>C:\temp\py\t.py t created t started t joined Done! x got deleted!
Vielen Dank! Es scheint, dass Mark das Programm verhält sich anders unter CPython 2.5 und 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!"
Emits (unter 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!
Und:
Python 2.6.2 (r262:71600 Sep 19 2009 17:24:20)
t created
t started
x got deleted!
mydata deleted
t joined
Done!
Hier ist meine Antwort, da Ich kann die Schlussfolgerung in den vorherigen Antworten nicht sehen.
Ich fing an, das gleiche zu fragen und versuchte ein Testprogramm, das dem in anderen Antworten ähnlich ist, und meine Schlussfolgerung war, dass sie GCed früher als das Ende des Programms erhalten, was bedeutet, dass diese Referenzen als bestimmt werden können Müll, sobald der Faden selbst stirbt.
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)
Der Ausgang:
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
Wie Sie sehen können, die löschen ist scheinen, sobald der Thread stirbt passieren.
- 1. Wie hoch ist die Lebensdauer eines temporären Standardarguments für einen Referenzparameter?
- 2. Wie hoch ist die Lebensdauer des Speichers, der auf typeinfo :: name() verweist?
- 3. Wie hoch ist die Lebensdauer des Zieles von Pointer-to-Function auf ein Lambda?
- 4. Was ist die Lebensdauer eines ASP.NET MVC Controllers?
- 5. Wie hoch ist die Android Toolbar?
- 6. Wie hoch ist die maximale SMS-Nachrichtenlänge?
- 7. Wie hoch ist die Standardhöhe von UITableViewCell?
- 8. Wie hoch ist die Standardtastaturanimationsrate des iPhone?
- 9. Wie kann die Lebensdauer eines Drag/Drop-Vorgangs verfolgt werden?
- 10. Probleme beim Identifizieren eines Werts in einem Dropdown (Selenium Python)
- 11. Versucht, die vorletzte Position eines übereinstimmenden Werts
- 12. Python Thema nicht die Rückgabe des Werts
- 13. Lebensdauer eines Lambda-Ausdruck in Rost
- 14. gem5 Simulationszeit ist hoch
- 15. Rückgabe eines Array-Werts, wenn er in String enthalten ist
- 16. Abrufen eines Werts von einem Eingabeaufforderungsbefehl mit Python
- 17. Wie hoch ist eine Leistungssteigerung?
- 18. Schauspieler die Lebensdauer des Systems in WPF
- 19. lebensdauer der konstanten variablen?
- 20. Wie hoch ist eine Zeile in Bootstrap?
- 21. Wie hoch ist die Rechenkomplexität der arima() - Funktion in R?
- 22. Wie hoch ist die Mindestleistung für die Cross AppDomain-Kommunikationsleistung?
- 23. Hinzufügen eines Werts zu Sammlungselementen
- 24. Wie hoch ist die durchschnittliche Zeit für die schnelle Sortierung?
- 25. Inkrementieren eines Werts in Neo4j-Abfrage
- 26. Überschreiben eines Werts in einer Iteritems-Schleife
- 27. Auto-inkrementieren eines Werts in Firebase
- 28. Einfügen eines ganzzahligen Werts in ein Textfeld
- 29. Wie hoch ist die Zeitkomplexität beim Einfügen eines Knotens in einen binären Suchbaum?
- 30. Wie hoch ist die maximale Größe eines URL-Worts in einer URL?
Gute Analyse, aber das fehlende Bit ist, dass _mydata_ weggehen ist, was Sie brauchen - ich muss eine neue Antwort öffnen, um formatierten Code anzuzeigen, aber das Wesentliche ist das gleiche wie Ihres. –