Threading: Thread beenden und neustarten

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
jgillich
User
Beiträge: 16
Registriert: Donnerstag 15. September 2011, 16:20

Ich schreibe gerade eine Anwendung, die mittels Selenium eine Webseite automatisiert. Bei Selenium gibt es aber ständig nicht immer so reproduzierbare Fehler (bezüglich der aufgerufenen Webseite). Diese fange ich per try-except ab. Da ich aber im Falle eines Fehlers nicht mehr mit dem restlichen Code fortfahren kann, habe ich das jetzt per Threading gemacht.

Ich habe mir es so gedacht, dass ich im Falle einer exception den Thread per exit beende und ihn neu starte. Das funktioniert komischerweise aber nicht, beim Aufruf von exit beendet sich mein komplettes Script.
Ist meine Annahme, dass das nur den Thread beendet falsch oder liegt es vielleicht an meinem Code?
BlackJack

@jgillich: `sys.exit()` beendet den gesamten Prozess — unabhängig davon in welchem Thread die Funktion aufgerufen wird.

Vielleicht solltest Du statt Threads zu verwenden, die Ausnahmenbehandlung so machen, dass es nach der Ausnahme keinen restlichen Code mehr gibt, der abgearbeitet wird.
Benutzeravatar
ocoal
User
Beiträge: 32
Registriert: Mittwoch 20. Juli 2011, 22:44

Hallo,

Du könntest Deinem Thread ein threading.Event Objekt mit übergeben, dieses dann im Fehlerfall setzen und in Deinem Mainthread entsprechend prüfen, bzw. auf die "Setzung" warten.

Sobald der Mainthread dann die Setzung erkennt, bzw. im Falle der Freigabe durch event.wait() wieder aktiv wird, kannst Du den Thread erneut starten (einmal, mehrfach durch eine Schleife, wie auch immer).

Hier mal etwas Beispielcode, der vielleicht als Ideenanreiz dienen könnte:

Code: Alles auswählen

>>> import threading
>>> import time
>>> def do_something(event):
... 	time.sleep(10)
... 	event.set()
... 	
>>> e = threading.Event()
>>> e.is_set()
False
>>> something_thread = threading.Thread(target=do_something, arg s=[e])
>>> something_thread.start()
>>> e.wait() # <- unser Mainthread wartet nun 10 Sekunden (do_something) bis das Event gesetzt wird
True
>>> 
Edit: Achja, einen Thread kannst Du einfach beenden, indem Du mittels "return" den Thread-Handler (das target, die run() Methode, etc.) verlässt.

Beste Grüße,
-Colin-
jgillich
User
Beiträge: 16
Registriert: Donnerstag 15. September 2011, 16:20

Hallo, danke erstmal, das klärt schon einiges.

Nur schaffe ich es einfach nicht, den Thread parallel zum Elternprozess laufen zu lassen.

Mein Thread sieht in etwa so aus:

Code: Alles auswählen

from threading import Thread, Event
from time import sleep

class Name(Thread):
    def __init__(self):
        Thread.__init__(self)

        self.update_event = Event()
        self.start()
        self.join() # <-- hmm?

    def run(self):
        # initialisierung

        while True:
            if self.update_event.isSet():
                self.update()
            sleep(5)
            
    def update(self):
       # update...
Nachdem das Objekt im Elternprozess erstellt wird, soll eine GTK-Oberfläche starten. Das passiert aber erst, nachdem die run-Methode beendet wird. Laut Dokueintrag für join() mag das durchaus so gewollt sein, aber wenn nicht per join wie starte ich das ganze dann? Der direkte Aufruf von run erzeugt bei mir irgendwie ein komisches Verhalten des Threads, und das obwohl er der einzige ist und nicht auf Objekte von Ausserhalb zugreift, somit sollte eigentlich ja auch nichts schiefgehen... :K

Naja ich hoffe mal jemand kann mir helfen das ganze zu entwirren. :oops:
deets

Du startest einen thread mit *start*. Du wartest auf sein Ende mit *join*. Was du also da machst ist im Grunde einen extra thread zu starten, um dann die ganze Zeit darauf zu warten, dass er beendet wird - da kannst du dann auch gleich einfach alles im main-thread machen.
jgillich
User
Beiträge: 16
Registriert: Donnerstag 15. September 2011, 16:20

Hmm, tatsächlich? Dann stimmt mit meinem Code was nicht, beim Aufruf von start passiert nämlich so ziemlich garnichts. Ich schau da nochmal drüber und melde mich dann wieder. :)
Antworten