Threading in Python

  • Hallo alle zusammen,

    ich fummel mich gerade etwas in Tornado mit Python ein. Ziel ist es mehrere Pifaces und einen DHT11 über eine Weboberfläche verfügbar zu machen.
    Ich bin jetzt soweit, dass eigentlich alles so funktioniert, wie es soll - eigentlich.

    Probleme macht der lahme DHT11 Temperatur-feuchtesensor, der nur aller zwei Sekunden ausgelesen wird.
    Daher würde ich ihn gern in einem Thread auslesen lassen.
    Leider sehe ich bei Threads (threading) nicht so richtig durch.
    Macht das eurer Meinung nach überhaupt Sinn und hätte jemand ein ganz einfaches kommentiertes Beispiel für threading, bei dem eine Funktion innerhalb des Threads abläuft, in der z.B i von0-10 bis hochgezählt wird und i nebenbei an einer weitere, thread externe Funktion übergeben wird?

    Sorry aber ich steh grad echt aufm Schlauch :s

  • Du hast schon recht, ich kam auch nur deshalb auf die Idee, weil:
    Wenn der Fühler ausgelesen wird, steht mein Programm etwa 2-4 Sekunden und es ist nicht möglich weitere Eingaben zu tätigen. Deshalb war die Idee, den Sensor über einen parallelen Thread auslesen zu lassen. Dadurch würde er das Programm ja nicht mehr verzögern.
    Hättest du denn eine Alternative im Angebot?

  • Hi,

    ich würde mir dafür das Modul _thread (Python3) genauer ansehen.

    Dort kannst Du ganz bequem einen Thread starten, der im Hintergrund dauerhaft die Werte Deines Sensors ermittelt und die z.B. weitergibt.

    Über die Funktion start_new_thread kannst Du neue/weitere Threads starten, welche andere Funktionen ausführen.

    Dazu ein kleines Beispiel:

    Das script startet einen Hauptthread der im Hintergrund aktiv ist und nach 6 Sekunden endet. Währenddessen wird ein weiterer Thread gestartet, der in dieser Zeit parallel eine Aufgabe ausführt. Beide Thread ermitteln die aktuelle Uhrzeit.

    Der Vorteil ist, dass Dein Programm weiter läuft, selbst wenn ein Thread durch einen Fehler aussteigt.

    Versuch Dich mit Threads anhand Deines scriptes.

    Mfg

    “Don’t comment bad code - rewrite it.”

    Brian Kernighan

    Einmal editiert, zuletzt von sls (21. Mai 2015 um 19:19)

  • HAH!

    Super danke Dir für die Hilfe erst wollte es gar nicht klappen, bis ich dann endlich gecheckt habe, dass unter Python 2 thread ohne Unterstrich daherkommt :wallbash:
    , jetzt klappts endlich. Ich hätte viel früher mal hier nachfragen sollen.

    :thumbs1:

    MFG Alberts


  • Hi,

    ich würde mir dafür das Modul _thread (z.B. Python3) genauer ansehen.

    Hi,

    sorry, das war wohl etwas missverständlich geschrieben. Damit meinte ich eben dass _thread das Modul für Threads unter Python 3 ist.

    Mfg und viel Spaß damit,
    sls

    “Don’t comment bad code - rewrite it.”

    Brian Kernighan

  • Hallo,

    ich habe den unten stehenden code mit "python3 thread.py" versucht auszuführen bekomme aber immer folgende Fehlermeldung. Die Fehlermeldung unter Linux und Windows mit IDLE ist die selbe. Ich habe danach gegoogelt aber leider bin ich aus den Funden nicht wirklich schlau geworden und mein Wissen was die Programmierung betrifft ist doch eher rudimentär.

    Code
    Hauptthread 05:56:24
    Traceback (most recent call last):
      File "thread.py", line 21, in <module>
        _thread.start_new_thread(zeit,())
    TypeError: first arg must be callable

    Also wenn mich jemand in die richtige Richtung drehen würde wonach ich zu suchen habe wäre ich dankbar.

    gruß
    co8

    Hab noch ein wenig rumgestümpert und mit folgenden anpassungen hat es funktioniert.

    Einmal editiert, zuletzt von co8 (25. Mai 2015 um 06:14)

  • Ja das ist klar, weil du sowohl eine Funktion als auch eine Variable mit dem selben Namen hattest. Sowas sollte man, wie du gemerkt hast, vermeiden :D

    Also gewöhnt euch am besten sofort an den Variablen aber auch Funktionen passende Namen zu geben, das mag vllt manchmal etwas mühsam sein, aber ist nicht nur übersichtlicher sowie leichter zu verstehen, sondern vermeidet auch Fehler ;)
    Denkt auch dran das es gut sein könnte, dass ihr den Code lange Zeit nicht betrachtet, in ein paar Jahren aber vielleicht mal was ändern wollt aber dann nicht mehr wisst wofür was ist oder wieso ihr das damals so gemacht hattest etc...

    Desweiteren macht das 'return' in der Form auch kein Sinn, kann also auch weggelassen werden, ebenso wie "zeit = time.localtime()" nicht gebraucht wurde da das bei "time.strftime" eine Optionale Angabe ist, die eigentlich dazu dienen soll _nicht_ die Aktuelle Zeit zu verwenden - da du aber die aktuelle ausgeben willst brauchste auch kein 2.Argument angeben.

    Auch hilft es oft Kommentare zu setzen:

    [code=php]
    # modules
    import time, _thread

    # second thread
    def new_thread():
    print("Second Thread")
    for i in range(5):
    print(i, time.strftime("%H:%M:%S"))
    time.sleep(1)
    print("End Second Thread")


    #start second thread
    _thread.start_new_thread(new_thread, ())
    time.sleep(0.5)
    # main thread
    print("Main Thread", time.strftime("%H:%M:%S"))
    #do some stuff in main thread to block it
    time.sleep(6)
    print("End Main Thread", time.strftime("%H:%M:%S"))
    [/php]

  • Hi,

    während des Erstellens der Antwot fiel mir damals auf, dass die Bezeichnung missverständlich sein könnte, weshalb ich die Variablen/Funktionsbezeichnungen geändert habe. Dass das mit hoher Wahrscheinlichkeit in den meisten Fällen ein Fehler ist, ohne es nochmal in der IDE zu überprüfen, dürfte die Fehlermeldung gezeigt haben.

    In Zukunft fertige ich hier nur noch Code ab, den ich bei Änderungen erneut teste.

    Mfg,
    sls

    “Don’t comment bad code - rewrite it.”

    Brian Kernighan

    Einmal editiert, zuletzt von sls (25. Mai 2015 um 12:04)

  • Hallo meigraf und sls,

    vielen Dank für Eure Antworten und Erklärungen.

    Das "zeit" 2 mal vergeben war ist mir gar nicht aufgefallen. Ich hatte mich nur gewundert was die Zeile

    Code
    zeit = time.localtime()

    bewirken sollte. Nachdem ich damit rumgespielt hatte und ich damit keine Ausgabe erzeugen konnte hatte ich sie einfach auskommentiert und die Aufrufe herausgenommen.

    Aber nun bin ich wieder mal ein bischen schlauer ;)

    gruß
    co8

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!