Wie kann ich laufenden Thread neu starten?

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.
BlackJack

@Campionissimo: Man kann einen Thread nur einmal starten. Das steht hier aber weiter oben auch schon irgendwo. Du musst einen neuen nehmen.
LivingOn
User
Beiträge: 33
Registriert: Montag 11. August 2008, 07:53

deets hat geschrieben:@LivingOn
Wozu denn das gelocke? Das bremst doch nur den cancel-rufenden Thread unnoetig aus in der Laenge der "wichtigen" Arbeit - und bringt nix, da dank dem GIL das umsetzen eines Attributes eh atomar ist. Selbst wenn es das nicht waere, koenntest du immer noch nur den Test und das canceln locken, wenn's denn sein soll.
Der Code stammt aus einem meiner Projekte und es war mir dort wichtig, dass während der Thread "arbeitet", kein Abbruch erfolgen sollte. Sicherlich kann man den Lock auf das Nötigste beschränken, dann geht aber ein Teil der Dokumentation flöten: "run() als auch stop() sind als Ganzes atomar!". Während run() läuft, kann nichts unterbrochen werden und während stop() läuft, kann kein run() mehr starten.
deets

Aber damit machst du dir ja die Nebenlaeufigkeit kaputt. Normalerweise wuerde man das nicht so machen wie du (und im uebrigen auch ein Lock immer in einem finally releasen, bzw. mit einem with-statement aquirieren), sondern eben kleinteilig, und wenn man in stop auch noch auf das Ende der laufenden Operation warten mag, dann macht man halt einen Thread.join.
LivingOn
User
Beiträge: 33
Registriert: Montag 11. August 2008, 07:53

deets hat geschrieben:Aber damit machst du dir ja die Nebenlaeufigkeit kaputt. Normalerweise wuerde man das nicht so machen wie du (und im uebrigen auch ein Lock immer in einem finally releasen, bzw. mit einem with-statement aquirieren), sondern eben kleinteilig, und wenn man in stop auch noch auf das Ende der laufenden Operation warten mag, dann macht man halt einen Thread.join.
Wieso macht man sich damit die Nebenläufigkeit kaputt?
Der Thread läuft parallel zum Hauptprogramm (also nebenläufig). Ob ich nun mit einem join oder Lock auf die aktuelle Operation warte, ist gehupft wie gesprungen. Wenn Exceptions in der Verarbeitung zu erwarten sind, sollte man natürlich im finally das Lock wieder freigeben. Da ich aber nur ein einfaches Beispiel bringen wollte und der Code so wie er da steht keine Exception wirft, halte ich Deine These "immer in einem finally releasen" für ein wenig überzogen. Es gibt viele Möglichkeiten wie man so etwas implementieren kann. Ich maße mir allerdings nicht an, andere Lösungen von vornherein in Frage zu stellen, nur weil sie nicht so funktionieren, wie ich es für richtig halte.
BlackJack

@LivingOn: Also das mit dem ``finally`` würde ich nicht für optional halten. Man weiss eigentlich nie sicher das etwas ausnahmefrei ist. Es kann zum Beispiel immer ein `MemoryError` auftreten. Und in dem Kommentar wo steht, dass dort die Aufgabe erledigt werden kann, ist allgemein *jede* Ausnahme möglich. Also erwartet man an der Stelle auch grundsätzlich das eine Ausnahme auftreten könnte und sollte dementsprechend defensiv programmieren.

Das mit dem Lock ist eine ziemlich sinnfreie Lösung. Das festzustellen ist IMHO nicht anmassend. Das `runflag` kann man nur *vor* dem Start des Threads, oder *nachdem* `run()` bereits abgearbeitet wurde mittels `stop()` auf `False` setzen. Vor dem Start könnte man sich stattdessen auch einfach entscheiden den Thread gar nicht erst zu starten und nach dem abarbeiten ist „anhalten” Unsinn. Die Methode stoppt nichts, auch wenn sie so heisst (und *das* eigentlich gefragt war) sondern ist nur eine umständlichere Art von `join()`, dass es schon gibt. Was genau löst die Methode also?
deets

LivingOn hat geschrieben: Wieso macht man sich damit die Nebenläufigkeit kaputt?
Der Thread läuft parallel zum Hauptprogramm (also nebenläufig). Ob ich nun mit einem join oder Lock auf die aktuelle Operation warte, ist gehupft wie gesprungen. Wenn Exceptions in der Verarbeitung zu erwarten sind, sollte man natürlich im finally das Lock wieder freigeben. Da ich aber nur ein einfaches Beispiel bringen wollte und der Code so wie er da steht keine Exception wirft, halte ich Deine These "immer in einem finally releasen" für ein wenig überzogen. Es gibt viele Möglichkeiten wie man so etwas implementieren kann. Ich maße mir allerdings nicht an, andere Lösungen von vornherein in Frage zu stellen, nur weil sie nicht so funktionieren, wie ich es für richtig halte.
Klar gibt es viele Moeglichkeiten. Aber die sind nicht alle gleich gut, und das, was du da praesentiert hast, widerspricht in mehreren Punkten ueblichen und besseren Praktiken. Und es zu kommentieren ist nicht anmassend, sondern verhindert, dass sich andere daran unreflektiert ein Beispiel nehmen. Das du persoenlich besser weisst, was du da getan hast und was nicht, und das es auch fuer dich sinnvoll war im urspruenglichen Kontext - geschenkt.

Aber hier geht es ja um einen allgemeineren Ansatz zur Thread-Synchronisation, und da ist eben weder der Verzicht auf try/finally noch eine "ich warte immer bis zum bitteren Ende" geeignet.
Campionissimo
User
Beiträge: 102
Registriert: Montag 28. März 2011, 07:50

Hallo Zusammen,

habe es endlich hingebracht.
Dafür hab ich ein andere Problem.
Mit meiner GUI steuer ich die Threads beginnen und beenden.
Wenn ich den START Button drücke laufen meine Threads.
Jetzt beende ich sie.
Dann möchte ich sie neustarten.
Wenn ich auf den START Button drücke.
Wenn jetzt noch nicht alle Threads beendet worden sind. Muss ich nochmal drücken.
Um das zu vermeiden wollte ich eine while schleife einbauen.
Aber da hängt sich meine GUI auf.
Welche wartefunktion kann man da nehmen ohne das sich die GUI aufhängt und auf eine Bedingung warten.

Vielen
Dank
deets

Du solltest das so loesen, dass START inaktiv ist, solange noch threads laufen. Und mit einem Timer kannst du alle paar 100 Millisekunden checken, ob die schon alle beendet sind oder nicht. Sobald alle fertig sind, aktivierst du START wieder.

Wie ein Timer & enable/disable genau geht, haengt von deinem GUI-toolkit ab.
Campionissimo
User
Beiträge: 102
Registriert: Montag 28. März 2011, 07:50

Das ist ja das Probelm.

Ich möchte wenn einmal Start gedrückt wurde. Und noch Threads am laufen sind eine warte funktion so lange aktiv ist bis alle threads weg sind und dann automatisch startet.
Wie ich dich verstanden habe ist es so wenn start gedrückt wurde und noch threads aktiv sind. soll ich kurze zeit später wieder start drücken
deets

Also, zum einen drueckst du dich hier in einem dermassen vermurksten Deutsch aus, dass es schwer ist, dich zu verstehen. Wenn es dir moeglich ist, formuliere bitte praeziser, mit den richtigen Satzzeichen an den *halbwegs* richtigen Stellen. Jeder macht Fehler, aber Muehe geben darf man sich schon.

Und nun zu deinem Problem: dann machst du das halt so, dass du durch Start-druecken einen Timer startest, der periodisch checkt, ob alle Threads beendet sind. Wenn ja, dann startet er sie neu, und deaktiviert den Timer.
Antworten