Daimonion - Do 20.12.07 17:16
Titel: Alternative zum aktiven Warten
Hoi
Irgendwie ist die Thematik geradezu diletantisch aber ich komm noch nicht so richtig mit den Gedanken klar.
Bevor ich mein Problem schildere und auf eure Meinung hoffe, möchte ich mal kurz meine Umgebung anreißen.
Ich hab einen PC der ein Schrittmotorkarte enthält. Diese Karte hat ein Hochspracheninterface und ich kann aus meiner Applikation heraus diverse Funktionen aufrufen. So kann ich zum Beispiel diverse Eingänge oder unterschiedliche Statusabfragen durchführen indem ich die zugehörige Funktion aufrufe und dann die Ergebnisse in meiner Applikation verarbeiten kann.
Hier mal ein kurzer Auszug um eine Variable zu lesen.
Delphi-Quelltext
1:
| rdaxstb(achsennummer, Wert) |
Damit kann ich zum Beispiel ein Bit auslesen, welches mir anzeigt, ob die gewählte Achse noch ein Profil verfährt, oder nicht mehr.
Nun vielleicht etwas mehr zu meinem Problem.
Momentan sind diverse Verfahrprozeduren realisiert und unter bestimmten Umständen tritt der Fall ein, dass ich die Achsen mittels einer Funktion des Hochspracheninterface stoppe.
Da die jeweiligen Achsen generell in ihrem Trapezprofil verfahren, bremsen sie sich mittels der angegebenen Verzögerungsgeschwindigkeit ab. Dies dauert, wie man sich denken kann, eine gewisse Zeitspanne (sagen wir mal 100 ms)
Während dieser Zeit darf ich keine anderen Verfahrdatensätze starten. Um sicherzustellen das die jeweiligen Achsen wirklich stehen, kann ich die oben angebene Prozedur aufrufen und die Variable auswerten um festzustellen ob die Achse schon steht.
Zum einen kann ich das ja mittels aktivem Warten machen
Delphi-Quelltext
1: 2: 3: 4: 5:
| Wert := 0; while Wert = 0 do begin rdastb(Achsennummer,Wert); sleep(50); end; |
Wie wir hoffentlich auch alle Wissen ist diese Art des Wartens doch sehr Prozessorbelastend und ich bin auf der Suche nach einer Alternative, die mir den Prozessor schont.
Bei der Suche nach diesen Alternativen stolpere ich allerdings immer über die Tatsache das mir nichts einfällt, wie man die ganze Geschichte Prozessorsparender gestalten kann.
Ich hab schon einen Watchdogthread laufen, aber der macht im Endeffekt auch nichts anderes als die Signale auszuwerten und über Funktionsaufrufe im Hauptprogramm irgendwelche Bits zu setzen. Im Hauptprogramm selbst muß ich dann aber wieder diese Bits mittels aktivem Warten überwachen.
Hoffe ihr habt mein Anliegen verstanden und könnt mir weiterhelfen. Sind ja doch einige Käpsele hier. ;)
Grüße
Moderiert von
Narses: Code- durch Delphi-Tags ersetzt
Lossy eX - Fr 21.12.07 11:37
Also ich muss gestehen, dass ich nicht genau weiß was diese Karte macht deswegen besteht ein gewisses Risiko, dass ich Falsch liege und Schwachsinn erzähle. ;)
Warum ist ein while sleep Code Prozessorbelastend? Das Sleep sorgt dafür, dass dein Thread such schlafen legt und andere Threads arbeiten können. Und sei es nur der Thread des Leerlaufprozesses der die CPU schlafen legt. Das Einzige was CPU Schonender wäre, wenn du mittels Event oder Callback über das Ende der Operation informiert werden würdest. Aber das gibt es vermutlich nicht.
Zu dem Code aus der DP: Ich bezweifel wirklich, dass er dir viel helfen wird. Denn man sollte sich dazu auch mal das
verlinkte original Posting [
http://www.delphipraxis.net/viewtopic.php?t=131] anschauen. Im Vergleich dazu ist diese Methode wirklich schonender. Aber die Abarbeitung von Windowsbotschaften (
Application.ProcessMessages) ist ja kein Bestandteil von dir. Zu mindest in deinem Code nicht. Und von daher würde der Code im Vergleich zu einem simplen Sleep lediglich dazu führen, dass dein Fenster reagieren würde. Du müsstest aber trotzden die externen Werte manuell abfragen. Ein vorzeitiges Abbrechen des Sleeps würde also nicht bzw. lediglich für Windowsbotschaften statt finden. Zusätzlich wäre so aber auch noch das Handling eines Events was bei einem Sleep nicht der Fall wäre.
Ich würde evtl. sogar empfehlen die Zeit etwas zu verkürzen. Wenn die Bibliothek nicht viel Rechenleistung braucht um den Wert abzufragen, dann kannst du auch ein Sleep von 1-10 benutzen. Denn so würdest du nicht immer mindestens 50ms Warten müssten. Und ob du 20 oder 1000 simple Abfragen hast stört eine CPU gar nicht. Und eigentlich ist so etwas auch ein nicht unüblicher weg.
Wenn deine Anwendung dabei aber nicht einfrieren soll, dann würde ich eher sagen, dass du die Zugriffe auf die Bibliothek in einen Thread auslagern solltest. Denn genau dafür sind Threads ja da. Der Weg über Application.ProcessMessages bringt nicht nur Vorteile. Er birgt auch einige versteckte sehr merkwürdige Verhaltensweisen. Mit einem Thread würdest du Befehle an ihn reichen und er würde sie abarbeiten und wenn nötig warten etc. Deine Anwendung wäre die ganze Zeit über flüssig bedienbar und der Thread wäre am Arbeiten. Allerdings würde ich zu Threads nur rate, wenn die Operationen zeitnah erledigt werden müssen und evtl. etwas länger dauern können. Also wenn deine Anwendung immer wieder stocken würde obwohl sie es nicht tun sollte. Ansonsten könnte es passieren, dass du dir mit einem Thread mehr Probleme als Vorteile an Land ziehst.