Forum: PC-Programmierung [Python] Thread beenden


von Rene K. (xdraconix)


Lesenswert?

Ich habe hier ein Python Scrip mit Multithreading, welches wie folgt 
aufgebaut ist (sehr verkürzt natürlich):
1
#!/usr/bin/python3
2
3
import threading
4
import time
5
6
class Aqua_Display (threading.Thread):
7
  def __init__(self, threadID, name, counter):
8
    threading.Thread.__init__(self)
9
    self.threadID = threadID
10
    self.name = name
11
    self.counter = counter
12
  def run(self):
13
    print("Start: " + self.name)
14
    OLED_system()
15
    print("Exit: "  + self.name)
16
17
def OLED_system()
18
  while True
19
    # Code zum dauerentem durchlaufen
20
21
# Create new threads
22
thread1 = Aqua_Display(1, "Display", 1)
23
24
# Start new Threads
25
thread1.start()


Gibt es da eine möglichkeit den Thread zu unterbrechen und zu beenden? 
Sowas wie thread1.stop() ?

Hat da jemand ein Tipp für mich?!

Liebe Grüße René

von Rolf M. (rmagnus)


Lesenswert?

Rene K. schrieb:
> Gibt es da eine möglichkeit den Thread zu unterbrechen und zu beenden?

Das ist (nicht nur in Python) normalerweise der falsche Weg. Ein Thread 
sollte sich selbst beenden. Von außen signalisiert man ihm dann, dass er 
das tun soll.

von Rene K. (xdraconix)


Lesenswert?

Super danke, also schonmal der richtige Hinweis.

Dann quasi in der def OLED_system() die while Schleife beenden damit er 
aus dem Thread selbständig aussteigt?!

Klingt vernünftig.

von Nur_ein_Typ (Gast)


Lesenswert?

Rene K. schrieb:
> Dann quasi in der def OLED_system() die while Schleife beenden damit er
> aus dem Thread selbständig aussteigt?!

Ganz genau so. Es gibt in Python keine Möglichkeit, einen Thread zu 
beenden -- und alle mir bekannten Möglichkeiten sind eher böse Hacks.

Dazu noch zwei Tipps: anstatt
1
threading.Thread.__init__(self)
 lieber
1
super().__init__()
 benutzen (ja, ohne Parameter self). Außerdem ist es meistens eine gute 
Idee, Thread.daemon auf True zu setzen, damit der Thread beim Beenden 
seines Prozesses automatisch beendet wird -- sonst muß man beim Beenden 
des Programms in der Konsole zweimal Strg+C eingeben, um erst den Prozeß 
und dann den Thread zu beenden. Deine __init__()-Methode sähe dann also 
so aus:
1
  def __init__(self, threadID, name, counter):
2
    super().__init__(self)
3
    self.daemon = True
4
    self.threadID = threadID
5
    self.name = name
6
    self.counter = counter

Übrigens hatte ich in Deinem anderen Thread [1] noch eine Rückfrage 
geäußert, aber leider keine Antwort erhalten. Wenn Du an dem anderen 
Thema noch interessiert bist, freue ich mich über eine Antwort in jenem 
Thread. ;-)

[1] Beitrag "Re: [Python] Kommunikation zwischen zwei Scripten"

von Rene K. (xdraconix)


Lesenswert?

Nur_ein_Typ schrieb:
> Rene K. schrieb:
>> Dann quasi in der def OLED_system() die while Schleife beenden damit er
>> aus dem Thread selbständig aussteigt?!
>
> Ganz genau so. Es gibt in Python keine Möglichkeit, einen Thread zu
> beenden -- und alle mir bekannten Möglichkeiten sind eher böse Hacks.
>
> Dazu noch zwei Tipps: anstattthreading.Thread.__init__(self)
>  liebersuper().__init__()
>  benutzen (ja, ohne Parameter self). Außerdem ist es meistens eine gute
> Idee, Thread.daemon auf True zu setzen, damit der Thread beim Beenden
> seines Prozesses automatisch beendet wird -- sonst muß man beim Beenden
> des Programms in der Konsole zweimal Strg+C eingeben, um erst den Prozeß
> und dann den Thread zu beenden. Deine __init__()-Methode sähe dann also
> so aus:
>   def __init__(self, threadID, name, counter):
>     super().__init__(self)
>     self.daemon = True
>     self.threadID = threadID
>     self.name = name
>     self.counter = counter
>
> Übrigens hatte ich in Deinem anderen Thread [1] noch eine Rückfrage
> geäußert, aber leider keine Antwort erhalten. Wenn Du an dem anderen
> Thema noch interessiert bist, freue ich mich über eine Antwort in jenem
> Thread. ;-)
>
> [1] Beitrag "Re: [Python] Kommunikation zwischen zwei Scripten"

Super, danke für deine Infos.

Oben schreibst du aber "ohne Parameter self" aber unten in deinem 
Beispiel hast den Parameter drinne. Hat dies einen Grund?

Wo liegt denn der Unterschied zwischen super(). und threading.Thread. ? 
Ich meine was macht super() anders?

von Sascha W. (sascha-w)


Lesenswert?

Rene K. schrieb:
> Super danke, also schonmal der richtige Hinweis.
>
> Dann quasi in der def OLED_system() die while Schleife beenden damit er
> aus dem Thread selbständig aussteigt?!
>
> Klingt vernünftig.
genau, anstatt while True einfach eine Variable einsetzen. Dann 
definierst du dir noch eine Funktion stop in der Klasse die dann die 
Variable auf False setzt. Problematisch wirds nur wenn die 
while-Schleife nicht regelmäßig durchlaufen wird weil z.B. dort eine 
Funktion auf irgend ein Ereignis wartet.

Sascha

von Nur_ein_Typ (Gast)


Lesenswert?

Rene K. schrieb:
> Oben schreibst du aber "ohne Parameter self" aber unten in deinem
> Beispiel hast den Parameter drinne. Hat dies einen Grund?

Ja, ein Fehler meinerseits. Beim zweiten Beispiel das "self" einfach 
wegdenken, bitte... ;-)

> Wo liegt denn der Unterschied zwischen super(). und threading.Thread. ?
> Ich meine was macht super() anders?

Die Funktion super() baut eine zusätzliche Schicht der Indirektion beim 
Aufruf der Methoden von Elternklassen ein. Wenn Du also morgen bemerkst, 
daß Du lieber von multiprocessing.Process anstelle von threading.Thread 
erben möchtest (etwa, um den Global Interpreter Lock (GIL) loszuwerden), 
dann mußt Du nicht alle Aufrufe von Elternmethoden umschreiben, weil 
super() Dir einen Proxy auf das richtige Objekt liefert. Auch im Kontext 
von Mehrfachvererbung ist super() eine feine Sache, mehr dazu liefert 
der Artikel [1] der im Allgemeinen für Python-Themen ausgesprochen 
empfehlenswerten Seite Realpython.com.

[1] https://realpython.com/python-super/

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.