Seite 1 von 1

Threading, Referenz main-/run thread

Verfasst: Montag 30. Mai 2022, 16:50
von NWA
Hallo Leute, ich versteh hier eine Kleinigkeit im Threading nicht.

Ich habe zu Testzwecken eine Hauptroutine, einen neuen thread und mein main thread. Dazu habe ich ein Event-objekt erstellt.

Wenn ich im main thread den Event stoppe, dann stoppt der main thread. Das klingt für mich noch plausibel, weil main thread ja auch ein thread ist.

Wenn ich aber den run thread stoppe und im main thread starte, dann startet der run thread. Das wiederum ist irritierend, weil ja nach obigem die Event-Referenz genommen wird aus dessen thread dieser verwendet wurde.

Meine Fragen lauten jetzt:
Wie kann ich von woanders den main thread starten und stoppen?

Code: Alles auswählen

import threading
from time import sleep


class ThreadTest2(threading.Thread):

    def __init__(self):
        super().__init__()
        self.MyEvent = threading.Event()  # set() und wait()

    #  run() thread
    def run(self):
        print("run, Start; ")
        sleep(1)
        self.MyEvent.wait()
        sleep(1)
        # self.MyEvent.set()
        print("run, Ende; ")

    #  main() thread
    def on_event(self):
        print("on_Event, Start; ")
        # self.MyEvent.wait()  # Wieso kann mit der run-Referenz der main() thread gestoppt werden?
        sleep(3)
        self.MyEvent.set()  # ...aber das startet den run() thread!
        print("on_Event, Ende; ")


# if __name__ == "main":
print("main START; ")
run_thread = ThreadTest2()  # eigenen thread erstellen
run_thread.start()  # hier startet run()
run_thread.on_event()  # main_Thread()-Methode mit run thread-Referenz
print("main ENDE; ")

Re: Threading, Referenz main-/run thread

Verfasst: Montag 30. Mai 2022, 17:11
von sparrow
Namen schreibt man in python klein_mit_unterstrich. self.MyEvent ist also eigentlich self.event.

Ich weiß auch nicht, was du mit "# Wieso kann mit der run-Referenz der main() thread gestoppt werden?" meinst. Wenn du run_thread.on_event() vom MainThread aus aufrufst, dann wird das nicht magisch in irgend einem anderen Thread ausgeführt sondern im MainThread. Und wenn du dort drin das Event mit set() zurück setzt, dann laufen natürlich alle anderen Threads weiter, die gerade auf das Event warten. Und wenn irgend ein Thread an dem Event ankommt, dann wartet er. Egal, welcher Thread das ist.

Re: Threading, Referenz main-/run thread

Verfasst: Montag 30. Mai 2022, 17:29
von __deets__
Du machst hier einen klassischen Fehler: du glaubst, eine von Thread abgeleitete Klasse bzw das Objekt, das du aus der erstellt hast, haette irgendwas mit einem Thread zu tun. Hat es nicht. Ein Objekt ist ein Objekt. Die Methoden und Eigenschaften, die es hat, unterliegen keiner magischen Zugriffskontrolle, die irgendwie in Bezug zu dem Thread stehen, in dem das Objekt erstellt wurde, oder dem Thread, der durch "start" gestartet, und implizit dann run ausfuehrt.

Entsprechend wird in deinem 'on_event' das Event-Objekt aus dem Thread benutzt, in dem die Ausfuehrung stattfindet. Rufst du da wait mittelbar via dem main-Thread auf, genauso wie ueber run, dann hast du zwei Threads, die beide auf das gleiche Event warten. Und das tun sie dann gleich Vladimir und Estragon - auf ewig, denn es kommt kein Godot, bzw. anderer Thread, der das Event setzt.

Re: Threading, Referenz main-/run thread

Verfasst: Mittwoch 1. Juni 2022, 19:13
von NWA
Ok, vielen Dank für eure Antworten.

Ich habe jetzt folgendes verstanden:
  • wait() betrifft immer den thread in dem es ausgeführt wird.
  • set() kann aber trotzdem den wartenden thread aus einem anderen thread wieder starten.
  • Das Event kann auch zwei threads stoppen.
  • Gibt es eine Möglichkeit threads aus anderen threads zu stoppen?

Re: Threading, Referenz main-/run thread

Verfasst: Mittwoch 1. Juni 2022, 19:35
von __deets__
Du meinst threads stoppen ohne das sie explizit auf ein event oder so etwas warten? Nein. Geht aus gutem Grund nicht.