threading und Event()

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
NWA
User
Beiträge: 38
Registriert: Mittwoch 3. Februar 2021, 11:40

Hallo, seit Tagen beschäftige ich mich threads, weil ich ein Problem habe:

1. Im thread soll eine Ressource geschrieben werden, welche aus dem Netzwerk zeitverzögert kommt.
2. Die Ressource soll aus dem aufrufenden Objekt heraus gelesen werden können.
3. Der thread soll gestartet und beendet werden können.

Es gibt zig Möglichkeiten, aber mir fehlt im Grunde eine grobe Richtung. Ich kann auch andere Bibs nehmen.

Mein letzter Stand ist mit Event(). Das erste wait() und set() funktioniert, aber ab dem zweiten wait() stoppt der thread nicht mehr. Ich habe keine Ahnung weshalb.

Code: Alles auswählen

from threadfile import threadclass
from time import sleep

thread1 = threadclass()  # thread erstellen

thread1.start()  # thread starten

sleep(5)  # ein wenig Warten
thread1.run_start()  # thread

Code: Alles auswählen

import threading
from time import sleep

wait2 = threading.Event()

class threadclass(threading.Thread):
    def __init__(self):
        super().__init__()
        self.daemon = False  # keine Auswirkung!
        self.ressource = 99  # Ressource die aus beiden Klassen gefunden werden soll

    def run(self):
        while True:
            print("run")  # Hier würde die Ressource geschrieben
            sleep(1)  # Damit es nicht so schnell ist
            wait2.wait()  # thread schlafen schicken

    def run_start(self):
        wait2.set()  # thread aufwecken
Sirius3
User
Beiträge: 18274
Registriert: Sonntag 21. Oktober 2012, 17:20

`threadfile` ist ein äußerst schlechter Modulname und `threadclass` ein schlechter Klassenname, der sich auch nicht an die richtige Groß-Klein-Schreibung hält. Du brauchst hier keine zwei Module und auch keine Klasse.
Benutze keine globalen Variablen.

Wenn ein Event einmal gesetzt ist, dann wartet natürlich niemand mehr auf das Event. Wenn Du die Ampel von rot auf grün schaltest, dann hält ja auch nicht das zweite Auto und wartet.
Dafür gibt es Event.clear:

Code: Alles auswählen

import threading
from time import sleep

def run_loop(event):
    while True:
        print("run")
        event.wait()
        event.clear()


def main():
    wait_event = threading.Event()
    thread = threading.Thread(target=run_loop, args=(wait_event,), daemon=True)
    thread.start()
    sleep(5)
    wait_event.set()
    sleep(3)
    wait_event.set()
    sleep(1)
    wait_event.set()

if __name__ == "__main__":
    main()
Ist aber nicht gut, weil set und clear nicht synchron sind. Für Deinen Anwendungsfall gibt es Semaphore.

Code: Alles auswählen

import threading
from time import sleep

def run_loop(semaphore):
    while True:
        print("run")
        sleep(2)
        semaphore.acquire()


def main():
    wait_semaphore = threading.Semaphore(0)
    thread = threading.Thread(target=run_loop, args=(wait_semaphore,), daemon=True)
    thread.start()
    sleep(1)
    wait_semaphore.release()
    sleep(1)
    wait_semaphore.release()
    sleep(5)
    wait_semaphore.release()

if __name__ == "__main__":
    main()
NWA
User
Beiträge: 38
Registriert: Mittwoch 3. Februar 2021, 11:40

:mrgreen: :mrgreen: :mrgreen:

Danke sehr, das passt super!
Sirius3
User
Beiträge: 18274
Registriert: Sonntag 21. Oktober 2012, 17:20

Bin ich doof. Semaphore arbeiten natürlich umgekehrt:

Code: Alles auswählen

import threading
from time import sleep

def run_loop(semaphore):
    while True:
        semaphore.acquire()
        print("run")
        sleep(2)


def main():
    wait_semaphore = threading.Semaphore()
    thread = threading.Thread(target=run_loop, args=(wait_semaphore,), daemon=True)
    thread.start()
    sleep(1)
    wait_semaphore.release()
    sleep(1)
    wait_semaphore.release()
    sleep(5)
    wait_semaphore.release()

if __name__ == "__main__":
    main()
NWA
User
Beiträge: 38
Registriert: Mittwoch 3. Februar 2021, 11:40

Alles ok, hatte das schon (aus versehen) richtig übernommen. Hast du deine erste Antwort korrigiert?
Antworten