Threads

Registriere dich jetzt, um exklusive Vorteile zu genießen! Als registriertes Mitglied kannst du Inhalte herunterladen und profitierst von einem werbefreien Forum.
Mach mit und werde Teil unserer Community!
  • Moin zusammen,

    ich bastel gerade für die Regelung der Pufferspeicher meiner Stückholzheizung eine neue Steuerung zusammen:


    Da das Einlesen von den DS18B20-Temperatursensoren rund 1 Sekunde pro Sensor benötigt, und ich im "Endstadium" rund 30 Sensoren haben werde, ist mir das ein bisschen lang. Ich muss Ventilmotoren zeitgenau anhalten, wenn sie einen Endschalter erreichen und ähnliches.


    Darum hab ich mich mit Threads beschäftigt:

    Die Raspberry Pi 3b hat vier Kerne. Ich kann also maximal 4 Threads gleichzeitig laufen lassen hab ich gelesen. Allerdings frage ich mich da, wo der Rest der Raspi (LXDE etc...) verarbeitet wird.


    Kann ich eine Funktion gleichzeitig aus verschiedenen Threads aufrufen?


    Zählt "this_thread" auch als thread? müsste ich den also bei die maximal 4 Threads beirechnen?


    Danke euch,


    Achim

  • Moin hunter_spike,


    du kannst einen Thread nicht einem bestimmten Kern zuordnen. Das Zuteilen sollte besser das Betriebssystem machen.

    Das Auslesen von 30 Sensoren in Threads aufzuteilen macht eigentlich keinen Sinn. Weil das Auslesen der Sensoren dauert auch da 1 Sekunde. Was macht denn deine Mainschleife in der Zeit??

    Kannst du mal schreiben in welcher Programmiersprache du das machen willst.


    Auch kann ich mir nicht vorstellen, das alle 30 Sensoren so wichtig sind.

    Man kann die Auslesezeit erheblich verkürzen wenn man nicht auf 12bit Genauigkeit besteht.

    Dann hat der Sensor eine Alarmfunktion. Die könnte man einsetzen um wichtige Temperaturwerte zu überwachen.


    Nu so meine Gedanken...


    73 de Bernd

    Ich habe KEINE Ahnung und davon GANZ VIEL!!
    Bei einer Lösung freue ich mich über ein ":thumbup:"

    Vielleicht trifft man sich in der RPi-Plauderecke.

  • Hallo Bernd,

    ich hab mich wohl zum Teil nicht richtig ausgedrückt.


    Ein Thread soll ganz gemütlich, alle 30 Sekunden, die Sensoren einlesen und die Werte ans Hauptprogramm übergeben.


    Ein anderer Thread schaltet einen Motor ein und wartet gespannt darauf, das der passende Endschalter kommt und er den Motor sofort ausschaltet.


    Sprache ist C++ .... wie dieses Forum....

  • Da das Einlesen von den DS18B20-Temperatursensoren rund 1 Sekunde pro Sensor benötigt, und ich im "Endstadium" rund 30 Sensoren haben werde,

    Da bist Du aber selber schuld, wenn Du die Sensoren im voreingestellten 12-Bit Modus verwendest. Siehe Datenblatt.


    Servus !

    RTFM = Read The Factory Manual, oder so

  • Bevor du ueber die Threadas nachdenkst solltest du verifizieren dass der Treiber fuer den DS18B20 ueberhaupt mehrere Threads gleichzeitig bedienen kann. Wenn der Treiber die Abfragen serialisiert hast du einfach eine Warteschlange vor dem Treiber...


    > Kann ich eine Funktion gleichzeitig aus verschiedenen Threads aufrufen?
    Kommt drauf an ob die Funktion reentrant ist.

  • OK.

    Um die 12 Bit hab ich mir keine Gedanken gemacht.

    Kurz gegoogelt würde ich dann grob 3 Sekunden statt 30 Sekunden für die Sensoren benötigen.

    Das werde ich später nochmal umstellen müssen, aber auch die 3 Sekunden sind zu lange, um die Endschalter der Motoren abzufragen. Somit muss ich mit Threads arbeiten, damit die Motorensteuerung parallel zur Datenerfassung läuft.

  • Bevor du ueber die Threadas nachdenkst solltest du verifizieren dass der Treiber fuer den DS18B20 ueberhaupt mehrere Threads gleichzeitig bedienen kann. Wenn der Treiber die Abfragen serialisiert hast du einfach eine Warteschlange vor dem Treiber...


    > Kann ich eine Funktion gleichzeitig aus verschiedenen Threads aufrufen?
    Kommt drauf an ob die Funktion reentrant ist.

    ich lese die Temperatursensoren nacheinander mit ifstream aus dem Verzeichnis "/sys/bus/w1/devices/"Sensornummer"/temperarure" aus.


    (wenn mir einer kurz erklärt wie ich eine Datei mit dem VNC-Viewer runter laden kann, könnte ich das Programm posten)

  • Wenn das verschiedene Geräte hinter den Dateinamen sind, dann liesse sich das schon parallelisieren, aber ich würde da eher mit ``select`` arbeiten als mit Threads. Wobei ich jetzt nicht weiss welche API man da unter C++ am besten nimmt. Denn die Frage nach der Programmiersprache machte schon Sinn, denn das Forum schränkt ja nur auf C oder C++ ein, aber nicht welche von beiden.


    Threads könnten weiterhin Sinn machen um Auslesen und Steuerung zu trennen falls das Auslesen sonst zu lange die Steueraufgaben blockieren würde.


    Zur Anzahl von Threads noch mal: Das System kann am Ende genau so viele Threads laufen lassen wie es gleichzeitig Prozesse laufen lassen kann, denn aus Sicht des Kernels sind Threads und Prozesse fast gleich. Der Hauptunterschied ist ob es getrennte Adressräume gibt oder nicht. Der Kernel entscheidet welche Threads (ein Prozess ist ja im Grunde auch ein einzelner Thread) auf welchem Kern für eine kurze Zeit ausgeführt wird, bevor dann nach einer (für Menschen sehr kurzen) Zeit wieder andere mal dran kommen und ein bisschen Prozessorzeit nutzen dürfen.

    Tradition is just peer pressure from dead people.


  • Das Programm ist noch im Versuchsstadium. Darum ein paar Sachen auskommentiert, vielleicht was doppelt, und bestimmt Fehler drin...

  • Rechtsklick auf das RealVNC-Symbol in der Taskleiste, dann auf "File Transfer..." (auf Deutsch vermutlich Dateiübertragung oder ähnlich).


    Edit: und wieder zu spät...

    Trotzdem Danke!

    Wenn dabei gestanden hätte, das das Kontextmenü mit der rechten Maustaste geht, hätte ich nicht so dumm fragen brauchen.... :saint:

  • Zum Beitrag # 11:

    Der Quelltext hat aus meiner Sicht mindestens 1 Designfehler:

    Die Funktionen laufen alle in einer Endlosschleife: while(1) kommt nie zu einem Ende. Das hat zur Konsequenz, dass bei einem Abbruch des Threads dieser in einem undefiniertem Zustand endet. Besser wäre es, eine Bedingung zu definieren, die die Funktion ordentlich beenden lässt (die im Thread ausgeführt wird) und damit auch den Thread ordnungsgemäß zu einem Ende kommen lässt. Ich frage mich, wie die join-Aufrufe funktionieren sollen, weil die in den Threads aufgerufenen Funktionen nicht enden.


    Ich bin kein Freund von Definitionen von namespaces. Meine bescheidene Erfahrung mit C++ hat ergeben, dass man besser versteht, was man tut, wenn man darauf verzichtet.

  • Ups :huh: 8|

    Man soll eben nicht alles glauben, was man im Netz liest.

    Hatte mehrmals gelesen das die Anzahl der Kerne die Threads bestimmt.

    Jein.


    Die Anzahl der Kerne bestimmt die Zahl der Threads, die gleichzeitig verarbeitet werden können. Generell ist es aber nicht unüblich, deutlich mehr Threads einzusetzen, als der Prozessor Kerne hat. Das kannst du auch selbst gut sehen, wenn du auf deinen Raspi einmal "ps -aux" aufrufst. All diese aufgelisteten Prozesse bestehen jeweils aus mindestens einem Thread.


    In der Regel (so auch bei dir, siehe das sleep(1)) wartet ein einzelner Thread nämlich ständig auf irgendwelche Dinge1 und in der Zeit könnte ein anderer Thread eben schnell auf dem Prozessor was rechnen.


    1 Das können die unterschiedlichsten Sachen sein:

    • Daten von der Netzwerkschnittstelle empfangen oder senden
    • Daten von der Festplatte lesen oder schreiben
    • Daten aus dem Hauptspeicher lesen oder schreiben
    • Auf ein bestimmtes Ereignis warten (Tastendruck, Mausbewegung, Bereitstellung eines Messwertes, Eintritt einer bestimmten Uhrzeit, Ablauf einer bestimmten Wartezeit)
  • Ich steh mal wieder auf dem Schlauch...

    Kann mir jemand sagen warum das unten stehende Programm funktioniert???


    Ich hab mit Sternchen markiert, wo meine Endschalter eingelesen werden und in eine Variable geschrieben werden.

    Darunter wird die Variable "Ventil1ist" anhand der Endschalter bestimmt.


    Rund 10 Zeilen weiter unten ist eine do-while-Schleife, in der ich nach meiner Auffassung so lange festhänge, bis "ist" und "soll" gleich sind.

    Demnach dürften sich aber meine Eingangs-Variablen nicht mehr ändern, da ich die ja weiter oben beschreibe.

    Warum funktioniert das Programm trotzdem?

    Wenn ich "Ventil1soll" eine Zahl zwischen 1-3 gebe, dann fährt mein Motor ordentlich bis auf die gewünschten Nocken und bleibt da stehen.


    Um es übersichtlicher zu machen habe ich ganz viel rausgekürzt.

    Wenns hilft poste ich auch alle 250 Zeilen....

  • Ich glaube, ich hab es selber gefunden....

    Ganz unten in "main" rufe ich ja "thread t1(Einlesen)" und "thread t4(Ventile)" auf.

    Kann es sein, das ich ganz viele "Einlesen" und "Ventile"-Funktionen am laufen habe???

  • Hier das komplette Programm: