Multi Threading mit Kernzuweisung bzw. Periodisierung möglich?

Heute ist Stammtischzeit:
Jeden Donnerstag 20:30 Uhr hier im Chat.
Wer Lust hat, kann sich gerne beteiligen. ;)
  • Das mit den Fehlerwerten verstehe ich nicht. Wie kann es denn bei Ausnahmen ein Problem sein herauszufinden welche Funktion die auslöst? Diese Information ist im Traceback enthalten. Das klingt als würden da mit Fehlerwert und vielen ``if``-Abfragen letztlich Ausnahmen selbst nachgebastelt.

    Und Ausnahmen heisst ja auch nicht das man die nicht auch direkt beim Aufrufer behandeln kann, ist dann halt ``try``/``except``/``else`` statt ``if``/``else``. Man ist dann aber flexibler welche Operationen vom ``try`` erfasst werden, dass heisst man muss bei mehreren Aufrufen nicht bei *jedem* manuell einen Fehlerrückgabewert prüfen, sondern kann die auch zusammenfassen. Und man muss nicht beim direkten Aufrufer die Ausnahmefälle behandeln, sondern kann das auch in höhere Ebenen verschieben. Naja, halt die Gründe warum Fehlerrückgabewerte doof und nervig sind, und man Ausnahmen erfunden hat. ?

    “Dawn, n.: The time when men of reason go to bed.” — Ambrose Bierce, “The Devil's Dictionary”

  • Multi Threading mit Kernzuweisung bzw. Periodisierung möglich?? Schau mal ob du hier fündig wirst!

  • Und Ausnahmen heisst ja auch nicht das man die nicht auch direkt beim Aufrufer behandeln kann, ist dann halt ``try``/``except``/``else`` statt ``if``/``else``. Man ist dann aber flexibler welche Operationen vom ``try`` erfasst werden, dass heisst man muss bei mehreren Aufrufen nicht bei *jedem* manuell einen Fehlerrückgabewert prüfen, sondern kann die auch zusammenfassen. Und man muss nicht beim direkten Aufrufer die Ausnahmefälle behandeln, sondern kann das auch in höhere Ebenen verschieben. Naja, halt die Gründe warum Fehlerrückgabewerte doof und nervig sind, und man Ausnahmen erfunden hat. ?

    Jaaaa wen ich so darüber nachdenke trifft es "nachgebautes try except" eigentlich ganz gut... bei Gelegenheit ändere ich das mal danke für den anstoss! :)

    Bzgl. Der leistung htop usw habe ich schon gemacht. Nutzt aber recht wenig denn bis das Programm reagiert inst der ruckler wieder weg.

    Ich verwende raspian light also eh schon ohne GUI und abgespeckt.

  • Denke bitte daran, dass man diese ganze Fehlerbehandlung sparsam einsetzen sollte. Im Grunde lernt man als Programmierer, dass man es nur in kleinen Bereichen nutzt, an welchen potentiell Fehler auftreten können die durch saubere Programmierung nicht vermieden werden können. Aber dann auch zielgerichtet.

    Simples Beispiel wäre bei einer Anwendung die eine SQL Light Datenbank nutzt eine Fehlerbehandlung die dafür sorgt, dass die Datenbank sauber wieder geschossen wird wenn etwas schief geht, damit die Datenbank danach nicht ewig schreibgeschützt bleibt sondern noch bevor das Programm im schlimmsten Fall abnippelt dieser sauber geschlossen wird.

  • Denke bitte daran, dass man diese ganze Fehlerbehandlung sparsam einsetzen sollte. Im Grunde lernt man als Programmierer, dass man es nur in kleinen Bereichen nutzt, an welchen potentiell Fehler auftreten können die durch saubere Programmierung nicht vermieden werden können. Aber dann auch zielgerichtet

    Ich glaube da muss ich etwas mehr zur Anwendung sagen.

    Der PI wird einmal gestartet und erfüllt mehrere Dienste (Sensoren, GSM etc. und macht Daten uploads, etc. siehe Threads)

    Wenn jedoch einer der Sensoren ausfällt oder fehlerhafte werte liefert etc. soll einfach 1 wert ins leere laufen. da bei der nächsten Abfrage idr. wieder ein richtiger wert auftritt. Auch muss sichergestellt sein das alles andere weiterläuft.

    Das ganze wird einmal gestartet und am besten erst nach 6 Monaten wieder abgeschaltet. deswegen ist es für mich sehr wichtig jede erdenkliche Fehlerquelle auszuschließen / zu behandeln. denn wenn etwas unerwartetes passiert bleibt das Programm stehen.

    Beispiel zu meiner Vorgehensweise.

    angenommen ich gehe über try explicit und benenne einen Division 0 Fehler da dieser der einzige zu erwartende ist.

    Nun bekommt einer der Sensoren aber eine falsche Information (externer Einfluss oder spinnt einfach) sodass ein type error entsteht der nicht als ausnähme definiert ist. dann Crash es...

    da meine zu verarbeitenden Daten absolut eindeutig in stringlänge werte Bereich usw. sind. erschien es mir einfacher und zuverlässiger diese auf Stimmigkeit zu prüfen und den folgenden code so zu schreiben, das kein Fehler auftritt wenn die Daten stimmen.

    Die chance das ich eine Fehlermeldung vergesse oder sich neue ergeben weil bpw. ein GSM Rückgabewert sich leicht verändert und die liste nicht mehr 6 oder 7 Inhalte hat, oder oder oder, erschien mir deutlich höher als ein einfaches. "passt der wert? ja? dann los! Nein? Hey hier stimmt was nicht!"

    zudem ich ja sowieso nur fehlerfreie Daten ansammeln möchte. also eine Prüfung ob der ermittelte Wert denn Sinn ergibt wäre sowieso angebracht.

    Also ja, Try and explicit ginge, wäre aber aus meiner Sicht fehleranfälliger. als ein kleiner if block hier ein Beispiel:

    def Sensorschleife(Delay):

    while true

    daten = Funktion_Sensoraufruf()

    if daten = error:

    print Fehler xy

    time.sleep(delay)

    return error

    Ablauf...

    return Ergebnis

    time.sleep(delay)

    T_Sensorschreife = threading...

    .

    .

    .

    if start Bedingung zur Initialisierung

    T_Sensorschleife.start()

    ich werde trotzdem die Startbedingungen bzw. Initialisierungen in try und Explicits packen das ist denke ich wie von euch beschrieben der saubere weg.

    vor allem um eben Schreibvorgänge zu beenden und den pi sauber zu erboten falls was kommt.

    Man lernt nie aus! ^^

  • Hallo,

    Zitat

    Ich glaube da muss ich etwas mehr zur Anwendung sagen.

    Nee. Anstatt zum x-ten deine Code wortreich zu beschreiben solltest du ihn einfach zeigen, oder Teile daraus. Außerdem bist du permanent dabei, deinen uns unbekannten Code zu rechtfertigen. Kannst du, ist uns im Prinzip egal - DU kommst ja so nicht weiter. Bzw. wenn du so vorgehst kannst du das Fragen nach Hilfe eigentlich auch direkt sein lassen.

    Basierend auf deiner wortreichen Beschreibung klingt es eher so, als hättest du ein ziemlich falsches Konzept, was Fehlerbehandlung und Umgang mit falschen Messwerten angeht.

    Gruß, noisefloor

  • Ich finde auch diese Textpassagen wenig hilfreich und mir erschließt sich nicht das Konzept ohne Code. Warum Sensoren abfragen in einem Thread? Ein einfache Funktion die bei dem eintreten der Bedingungen aufgerufen wird ist schnell abgearbeitet und erzeugt weniger Overhead als dieses ganze Threads Theater. Eine Fehlermeldung ausgeben, dann ein Sleep für einige Sekunden um dann einen Return zu machen? Warum nicht den Return sofort, auf was soll der Thread dann noch warten?

    So was führt ganz schnell zu Problemen und wenn du immer das Prinzip nimmst:

    Bedingung tritt ein = Thread erzeugen. Dann kann es bei deiner Konstruktion mutmaßlich ganz schnell passieren, dass die Bedingung für den Thread mehrfach eintritt und du dann hunderte oder gar tausende Threads hast die noch in ihrem Sleep warten endlich beendet werden zu können. Spätestens wenn irgendwann der Garbage Collector anfängt deinen Unrat rauszutragen, dann kann es ganz schnell sehr zäh werden.

    Vielleicht hast du auch das Konzept nicht ganz verinnerlicht. Du schaust Bedingung für Thread = True dann Thread starten. Ab diesem Punkt läuft dein Code weiter und wenn du nun wieder an dem Bedingung Prüfen kommst und nicht prüfst ob sich ein Thread gerade darum kümmert, dann wird der nächste gestartet und so weiter.

    Daher Bedingung prüfen, Funktion bei Bedarf aufrufen und fertig. Solche Dinge wie Threads sind Experten Dinge, du kannst dir damit schnell einen Code erstellen der unmöglich zu debuggen ist. Ein sinnvollere Anwendung für Threads wäre z.B einer der sich um die grafische Ausgabe kümmert, während ein weiterer dafür sorgt, dass die Daten die von der Ausgabe gebraucht werden aktuell gehalten werden. Aber Threads sollten nicht als Ersatz für Funktionen genutzt werden.

    Es gibt unheimlich viele Fallstricke und genau deshalb nutzt man Threads sehr bedacht.

  • Hallo Heinoderrblaue,

    angenommen ich gehe über try explicit und benenne einen Division 0 Fehler da dieser der einzige zu erwartende ist.

    Kann man das nicht abfangen?

    In meiner Lieblingsprogrammiersprache kann ich solche Laufzeitfehler ignorieren und daraus wird ein Fehler, der vergleichbar mit dem Scheitern eines Vergleiches wird. Also belanglos.

    Diese Fehler kann ich loggen (Datumszeitstempel, Quellcode-Zeile, an dem der Fehler auftrat). Und irgendwann schaue ich mir die Logdatei an, um die fehlerträchtigen Zeilen zu identifizieren.

    Beste Grüße

    Andreas

    Ich bin wirklich nicht darauf aus, Microsoft zu zerstören. Das wird nur ein völlig unbeabsichtigter Nebeneffekt sein.
    Linus Torvalds - "Vater" von Linux

    Linux is like a wigwam, no windows, no gates, but with an apache inside dancing samba, very hungry eating a yacc, a gnu and a bison.

  • Kann man das nicht abfangen?


    In meiner Lieblingsprogrammiersprache kann ich solche Laufzeitfehler ignorieren und daraus wird ein Fehler, der vergleichbar mit dem Scheitern eines Vergleiches wird. Also belanglos.

    Ja man kann jede Art Fehler abfangen oder auch explizit bestimmte Fehler. Macht ja auch Sinn, wenn fiktiv eine Verbindung zur Datenbank scheitert sollte das Programm ja anders reagieren als wenn das speichern eines Wertes darin nicht funktioniert.

    Bei dem geschilderten Fall könnte man sich eine Fehlerabfrage auch sparen, indem man einfach sicherstellt, dass der Wert valide ist. Ein simples Beispiel wäre die Eingabe durch einen regulären Ausdruck auf Plausibilität zu prüfen. Das geht extrem schnell und man schließt (korrekt angewendet) auch Werte aus die einen Fehler verursachen können.

    Dabei sollte man aber auch beachten, dass nicht jeder Wert der gültig ist oder nicht zu einem Fehler führt auch tatsächlich korrekt ist. Meldet ein Sensor im fiktiven Bereich 0-100 eine falsche 25 statt richtiger 68 weil irgendwo ein Byte gekippt, dann ist der Wert auch falsch, aber nicht offensichtlich falsch. Da sollte man jeden Wert mit vorherigen vergleichen um zu prüfen ob das Muster erwartbar ist, oder offensichtlicher Unsinn darstellt. Beispiel, wenn ein Temperatursensor im Keller 10 Messungen im Abstand von 5 Minuten immer 25°C hat und plötzlich 600°C anzeigt, dann ist das offensichtlich falsch, führt aber zu keinem Problem in der Verarbeitung oder Speicherung, sollte der Wert wider erwarten korrekt sein, dann sollte man sich einmal Gedanken darüber machen die Feuerwehr zu dem Problem hinzuzuziehen :)

    3 Mal editiert, zuletzt von InterGeek (12. Januar 2022 um 19:29)

  • Hallo,

    Kann man das nicht abfangen?

    Log-Datei:

    Terminalausgabe:

    Code
    10.0
    5.0
    3.3333333333333335
    2.5

    Als kleines Beispiel, Formatierungen und viele Anpassungen sind möglich.

    Grüße

    Dennis

    🎧 With the music execution and the talk of revolution, it bleeds in me and it goes 🎧

  • Hallo,

    Kann man das nicht abfangen?

    Klar kann man das. Es ging ja in den letzten 10 Posts darum, dass die Vermutung nahe liegt, dass der TE an der Programmiersprache seiner Wahl (=Python) vorbei programmiert und keine saubere Struktur von Fehlerbehandlung und Datenvalidierung hat. Was aber, so habe ich inzwischen den Eindruck, sekundär ist, weil ein nicht ruckelnder Videostream aus einem Python-Thread heraus wichtiger ist *SCNR*

    Gruß, noisefloor

  • also das ruckeln hat sich aufgeklärt... ich hatte schlicht schlechten empfang :wallbash::wallbash:

    stärkere antenne hat geholfen... :stumm:


    Trotzdem vielen Dank für all die ratschläge mit try und explicit sowie log dateien (kann ich ja aucj an den server jagen) werd ich mich auf jedenfall ranhalten!


    Zum Auslagern von Funktionen hätte ich noch eine generelle Frage.

    Macht Man das anhand irgendeiner faustregel oder einfach wie man lustig ist?

    Ich habe es gerade in themengebiete geteilt aber überlege es um zu sortieren um weniger imports zu haben oder ist das am ende vollkommen egal?

    Sorry für den ganzen heck meck und danke für eure Zeit! :) :bravo2::wallbash:

  • Hallo,

    Zitat

    Macht Man das anhand irgendeiner faustregel oder einfach wie man lustig ist?

    So dass es sinnvoll isr, man möglichst keine Coderedundanz hat und jede Funktion genau das macht, was sie soll.

    Zitat

    um weniger imports zu haben oder ist das am ende vollkommen egal?

    Kommt drauf an.

    Gruß, noisefloor

  • Heinoderblaue Die Beschreibung von der Fehlerbehandlung funktioniert so nicht, denn es kann ja trotz prüfens und Fehlercodes irgendwo eine Ausnahme ausgelöst werden mit der Du nicht rechnest. Also Ausnahmen musst Du sowieso behandeln. Und wenn Du sowieso schon Ausnahmebehandlung hast, dann kannst Du die halt auch richtig nutzen statt *zusätzlich* auch noch irgendwelche Fehlercodes *mit deren Nachteilen* dazu zu basteln.

    “Dawn, n.: The time when men of reason go to bed.” — Ambrose Bierce, “The Devil's Dictionary”

  • Macht Man das anhand irgendeiner faustregel oder einfach wie man lustig ist?

    In der Praxis ist es so, dass man in Funktionen Dinge ablegt die entweder an verschiedenen Stellen gebraucht werden oder die man der Übersichtlichkeit zuliebe aus z.B einer Schleife auslagern will. Die Faustregel ist also simpel gesagt: Funktionen dienen dazu wiederverwertbaren und übersichtlichen Code zu schreiben.

    Simples Beispiel Auslesen eines Sensor könnte man in eine Funktion (außerhalb des Hauptprogramms) ablegen und diesen Teil in jedem beliebigen anderen Programm dann auch wiederverwenden.

    Eine Sinnvolle Funktion wäre z.B "SchreibeLog(ziel, eintrag, usw)" in deinem Fall welche sich darum kümmert das ein Eintrag in das richtige Log in der richtigen Form landet. Dann musst du im Code nicht ständig Datei öffnen, schreiben und so weiter. Wenn dann ein Fehler auftritt, dann weißt du ohne viel Debuggen, dass die Quelle vermutlich innerhalb der Funktionen liegen muss die ein Log schreibt.

  • Und man kann Funktionen auch separat und automatisiert testen.

    Wobei `SchreibeLog()` (also eigentlich `schreibe_log()`) inhaltlich vielleicht kein so gutes Beispiel ist, weil es dafür schon mehrere fertige Lösungen gibt, die man eher nicht neu erfinden sollte. In der Standardbibliothek das `logging`-Modul oder das von Dennis89 gezeigte, externe `loguru`. `loguru` hat auch einen praktischen Decorator/Kontextmanager `logger.catch()` um in einer Funktion/Methode oder einem ``with``-Block, automatisch alle dort nicht behandelten Ausnahmen zu protokollieren. Wobei man das auch auf bestimmte Ausnahmen beschränken kann.

    “Dawn, n.: The time when men of reason go to bed.” — Ambrose Bierce, “The Devil's Dictionary”

Jetzt mitmachen!

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