Hallo zusammen,
alle paar Wochen steh ich vor dem selben Problem, ich will einen laufenden Thread beenden, weiß aber nicht wie.
Bis jetzt konnte ich noch immer Events oder ähnliche einbauen , damit ich den Thread gezielt beenden konnte. Jetzt habe ich allerdings einen Thread in dem eine massive Rechnung abläuft (Laufzeiten von mehreren Minuten möglich). Der Benutzer sieht im GUI Thread einen Prozessbalken und soll zusätzlich auf abbrechen klicken können, wenn er die Rechnung stoppen will.
Wie beende ich einen Thread der mitten in der Ausführung ist?
threading.Thread von aussen beenden,abbrechen oder killen
Hallo.
Indem du zwischen den Berechnungen abfragst, ob ein Beenden-Event aufgetreten ist. Die Gewichtung von Laufzeit und Reaktionszeit bleibt dann natürlich noch dir überlassen.
Sebastian
Indem du zwischen den Berechnungen abfragst, ob ein Beenden-Event aufgetreten ist. Die Gewichtung von Laufzeit und Reaktionszeit bleibt dann natürlich noch dir überlassen.
Sebastian
Das Leben ist wie ein Tennisball.
Ich nehme an du erbst von threading.Thread, wenn dem so ist, is in deiner run-Methode eine While-Schleife, du ersetzt while True durch while self.meine_var
Code: Alles auswählen
class Xyz(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.ka_iwas = True
def run(self):
while self.ka_iwas:
print 'xyz'
sleep(1)
def stop_it(self):
self.ka_iwas = False
the more they change the more they stay the same
So mache ich das ja auch normalerweise, aber jetzt habe ich eine einzige Funktion, die lange Laufzeiten haben.
Der Benutzer wird die Abbrechen-Taste drücken wenn die Rechnung mitten in "funktionXYZ" steckt und muss dann das Ergebnis abwarten, obwohl er es nicht mehr will (Core-Last 100%). "funktionXYZ" ist eine Funktion aus einem importierten Modul.
Code: Alles auswählen
#hier könnte ich den Thread beenden
funktionXYZ(wert) #diese Funktion hat lange Laufzeiten (1s-3min je nach wert)
#hier könnte ich den Thread beenden
Dann geht das nicht. Aber du könntest statt threads das Multiprocessing-Modul nehmen, dessen Prozesse kannst du per .terminate() beenden.IoI hat geschrieben:So mache ich das ja auch normalerweise, aber jetzt habe ich eine einzige Funktion, die lange Laufzeiten haben.
Oder du startest 2 threads
Einen Thread der die Funktion in einem 2. Thread started, den 2. Thread machst du zum Daemon-Thread, dann killst du einfach den 1., sollte gehen oder?
Einen Thread der die Funktion in einem 2. Thread started, den 2. Thread machst du zum Daemon-Thread, dann killst du einfach den 1., sollte gehen oder?
the more they change the more they stay the same
Code: Alles auswählen
from threading import Thread
import time
from itertools import count
class Controller(Thread):
def __init__(self, func, args=None, kwargs=None):
Thread.__init__(self)
self.func = func
self.args = args or []
self.kwargs = kwargs or {}
self.running = True
def stop(self):
self.running = False
def run(self):
t = Thread(target=self.func, args=self.args, kwargs=self.kwargs)
t.setDaemon(True)
t.start()
while self.running:
time.sleep(0.1)
def worker():
for i in count():
print i
time.sleep(0.05)
c = Controller(worker)
c.start()
t = time.time()
time.sleep(2)
c.stop()
[url=http://wiki.python-forum.de/PEP%208%20%28%C3%9Cbersetzung%29]PEP 8[/url] - Quak!
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
Leider nicht, du nutzt in dem Skript nur aus, dass der Prozess beendet wird.jbs hat geschrieben:Funktioniert.Code: Alles auswählen
from threading import Thread import time from itertools import count class Controller(Thread): def __init__(self, func, args=None, kwargs=None): Thread.__init__(self) self.func = func self.args = args or [] self.kwargs = kwargs or {} self.running = True def stop(self): self.running = False def run(self): t = Thread(target=self.func, args=self.args, kwargs=self.kwargs) t.setDaemon(True) t.start() while self.running: time.sleep(0.1) def worker(): for i in count(): print i time.sleep(0.05) c = Controller(worker) c.start() t = time.time() time.sleep(2) c.stop()
hier dein Quelltext mit Anpassung:
Code: Alles auswählen
from threading import Thread
import time
from itertools import count
class Controller(Thread):
def __init__(self, func, args=None, kwargs=None):
Thread.__init__(self)
self.func = func
self.args = args or []
self.kwargs = kwargs or {}
self.running = True
def stop(self):
self.running = False
def run(self):
t = Thread(target=self.func, args=self.args, kwargs=self.kwargs)
t.setDaemon(True)
t.start()
while self.running:
time.sleep(0.1)
def worker():
for i in count():
print i
time.sleep(0.05)
c = Controller(worker)
c.start()
t = time.time()
time.sleep(2)
c.stop()
print "gestoppet!"
c.join()
print "Controller beendet"
while True:
print "schlafe"
time.sleep(1)
Code: Alles auswählen
import threading
import ctypes
import time
w32 = ctypes.windll.kernel32
THREAD_TERMINATE = 1 # Privilege level for termination
class DummyThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.setDaemon(1)
def run(self):
self.tid = w32.GetCurrentThreadId()
while 1:
print 'Running'
time.sleep(1)
def kill_thread(threadobj):
handle = w32.OpenThread(THREAD_TERMINATE, False, threadobj.tid)
result = w32.TerminateThread(handle, 0)
w32.CloseHandle(handle)
return result
if __name__ == "__main__":
print 'Starting thread...'
x = DummyThread()
x.start()
time.sleep(5)
print 'Terminating thread...'
kill_thread(x)
time.sleep(5)
print 'Exiting'
Das das "killen" offiziell nicht vorgesehen ist, sollte übrigens zu denken geben. Das hat ja Gründe. Zum Beispiel das man keinen definierten Zustand garantieren kann, wenn von aussen einfach so ein Thread hart beendet werden kann. Wenn man den "nativen" Thread killt könnte es sogar sein, dass der Python-Interpreter in einem inkonsistenten Zustand ist.
Multiprocessing wäre auch noch schneller als ThreadingDarii hat geschrieben:Dann geht das nicht. Aber du könntest statt threads das Multiprocessing-Modul nehmen, dessen Prozesse kannst du per .terminate() beenden.IoI hat geschrieben:So mache ich das ja auch normalerweise, aber jetzt habe ich eine einzige Funktion, die lange Laufzeiten haben.
the more they change the more they stay the same
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
Ooch, es gibt schon durchaus Systeme wo das starten von Prozessen hohen Overhead hat, so dass man das nicht prinzipiell sagen kann...Dav1d hat geschrieben:Multiprocessing wäre auch noch schneller als Threading
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Ganz interessant ist an dieser Stelle vielleicht http://java.sun.com/j2se/1.5.0/docs/gui ... ation.html sollte im groben auch für Python gelten.IoI hat geschrieben:Aber ich muss doch irgendwie etwas, was ich schon extra in einem eigenen Thread gestartet habe, wieder beenden können. Alles was in dem Thread ist kann weg, weil der User es nicht mehr braucht.
Auf Python bezogen, in 95% aller FälleLeonidas hat geschrieben:Ooch, es gibt schon durchaus Systeme wo das starten von Prozessen hohen Overhead hat, so dass man das nicht prinzipiell sagen kann...Dav1d hat geschrieben:Multiprocessing wäre auch noch schneller als Threading
the more they change the more they stay the same
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
Du meinst, 95% aller Python-User sind auf Windows order 95% aller Python-User sind auf Linux?Dav1d hat geschrieben:Auf Python bezogen, in 95% aller Fälle
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Nein, In 95% aller Fälle ist multiprocessing schneller als Threading, bezogen auf Python
the more they change the more they stay the same
Du fragst mich Sachen, ich meine die Zahl (95) mal in einem Vortrag gehört zu haben
Lieg ich denn falsch?
Lieg ich denn falsch?
the more they change the more they stay the same