Laden...

Probleme mit Genauigkeit von Thread.Sleep

Erstellt von christof.k vor 12 Jahren Letzter Beitrag vor 12 Jahren 5.660 Views
C
christof.k Themenstarter:in
159 Beiträge seit 2005
vor 12 Jahren
Probleme mit Genauigkeit von Thread.Sleep

Hallo,

seit einigen Jahren schreibe ich an einer Applikation, um Nachrichten gesteuert auf dem CAN Bus zu senden (mittels Vector Hardware, wenn dies jemanden was sagt).
Dazu nutze ich folgendes Konstrukt

while(1)
{
   SendeNachricht();
   Thread.Sleep(5)
}

um alle 5ms die Funktion ablaufen zu lassen der dann entscheided, was zu senden ist.
Dies hat bisher immer blendend funktioniert (über Jahre hinweg).
Im laufe der Zeit muss sich aber "irgend etwas" geändert haben. Denn nun wird mein Thread im Normalfall immer nur alle 15 ms ausgeführt (auch wenn ich Thread.Sleep(1) probiere). Ich habe das nur durch Zufall herausbekommen und kann deshalb nicht sagen, was sich in der Umgebung (Windows) geändert hat. Win XP war immer das Betriebssystem.
Es kann nicht an der Rechnerpower liegen, da ich eine Updaterate von 0,3 ms bekomme, wenn ich das Thread.Sleep weglasse. Dies blockiert aber natürlich einen Kern.
Wir ist klar, dass Windows kein Echtzeitbetriebssystem ist, aber da es über eine lange Zeit hinweg wunderbar funktioniert hat bin ich so verwundert.
Hat jemand hierzu vielleicht einen Tip?

Vielen Dank im Voraus.
Christof

T
415 Beiträge seit 2007
vor 12 Jahren

Schonmal versucht statt Thread.Sleep() einen Timer zu verwenden? Dieser blockiert dann natürlich das Programm auch nicht.

6.862 Beiträge seit 2003
vor 12 Jahren

Hallo,

ich kann mich t2t nur anschließen. Thread.Sleep als Timeralternative zu benutzen ist grober Unfug. Thread.Sleep wartet auch nur mindestens die spezifizierte Zeit. Es ist jederzeit möglich, dass Thread.Sleep erst später zurückkehrt. 5ms sind so oder so aber arg knapp. Allein durch das Thread Scheduling kanns zu viel längeren Wartezeiten kommen wenn es grad zu einem Threadwechsel kommt.

Baka wa shinanakya naoranai.

Mein XING Profil.

48 Beiträge seit 2010
vor 12 Jahren

Was passiert wenn Du die Priorität deines Prozesses erhöhst?

Zu den Timern gibt den tollen Artikel Comparing the Timer Classes in the .NET Framework Class Library, der u.A. die Präzision der Timer-Klassen behandelt.

C
christof.k Themenstarter:in
159 Beiträge seit 2005
vor 12 Jahren

Hi,
Timer hatte ich sehr früh mal versucht, doch haben diese noch einen größeren Overhead, so dass dieses sehr schnell in eine Sackgasse geführt hat.....oder verstehe ich Dich falsch?

Danke
Christof

U
1.688 Beiträge seit 2007
vor 12 Jahren

Hallo,

um die gewünschte Genauigkeit zu erreichen, kann man versuchen, mit einem Multimedia-Timer zu arbeiten. Dafür gibt's einen Wrapper bei Codeproject. Allerdings erreicht der die 5ms auch nur im Mittel.
Die 15ms sind übliche Dauer einer Zeitscheibe in Windows - das hat sich auch nicht kürzlich geändert. Verhält sich denn Dein Programm plötzlich anders?

C
christof.k Themenstarter:in
159 Beiträge seit 2005
vor 12 Jahren

Hi,

ich habe für eine lange Zeit nur noch an den Nachrichteninhalten herumgeändert und deshalb nicht die Updaterate beobachtet.
Deshalb denke ich, dass es vor einem Jahr noch wunderbar funktioniert hat....schon schräg.
Es gibt Tools von der Firma, die die HW Herstellt. Diese schaffen diese hohe Auflösung ohne einen Prozuessorkern aufzubrauchen....

Vielleicht hat ja jemand noch eine Idee?

Danke
Christof

T
415 Beiträge seit 2007
vor 12 Jahren

Es gibt Tools von der Firma, die die HW Herstellt. Diese schaffen diese hohe Auflösung ohne einen Prozuessorkern aufzubrauchen....

Die werden mit großer Wahrscheinlichkeit kein Sleep() verwenden. Da dieses, wie du schon selbst sagtest, einen ganzen Kern "lahm legt". Genau das umgehst du auch, wenn du einen Timer einsetzt. Ich weiß ja nicht, wie du deine Architektur aufgezogen hast, aber sollte es dir einigermaßen leicht möglich sein, dann empfehle ich dir zumindest mal testweise die Timer-Variante einzubauen und zu schauen, wie es sich dann verhält.

Hinweis von herbivore vor 12 Jahren

Thread.Sleep legt nichts lahm, außer dem Thread, der das Thread.Sleep aufruft. Thread.Sleep gibt den zuvor belegten Kern für andere Threads frei. Ein Thread der schläft verbraucht keine Rechenzeit.

C
christof.k Themenstarter:in
159 Beiträge seit 2005
vor 12 Jahren

Hallo,

habe gerade den Aufruf der Funktion durch einen Timer gesteuert und egal ob ich den "normalen" oder den Multimedia-Timer nutze, die schnellste Updaterate ist 15 ms.
Nur wenn ich eine Stopwatch in den Thread einbaue, die für genau 5 ms den Thread blockiert, bekomme ich das gewünschte Ergebniss.

Ich frage mich, wie dass andere kommerzielle Tools lösen, die eine hohe zeitl. Auflösung realisieren.

Bis bald
Christof

49.485 Beiträge seit 2005
vor 12 Jahren

Hallo christof.k,

wie andere Programme das machen, weiß ich nicht.

Wenn es bei dir vorher mit Thread.Sleep geklappt hat, war das wohl pures Glück. Die Ungenauigkeiten von Thread.Sleep (und leider auch von den meisten Timer-Typen) sind bekannt und wurden im Forum schon öfter thematisiert. Selbst mit 15ms Intervall, also 10ms Abweichung, hast du - bezogen auf Thread.Sleep (und die meisten Timer) - sogar immer noch ziemliches Glück.

herbivore

48 Beiträge seit 2010
vor 12 Jahren

Könnte er sich einen Vorteil verschaffen, wenn er zum senden der Nachricht an den CAN Bus den Latenzmodus des Garbage Collectors auf LowLatency setzt?

U
1.688 Beiträge seit 2007
vor 12 Jahren

Hallo,

der Multimedia-Timer hat prinzipiell eine Genauigkeit von 1ms. Wenn es bei Dir 15ms sind, hast Du was falsch gemacht.

den Latenzmodus des Garbage Collectors auf LowLatency setzt?

Kaum, da das Problem nichts mit dem GC zu tun hat, sondern systembedingt ist.

6.862 Beiträge seit 2003
vor 12 Jahren

Hallo,

ist es denn überhaupt nötig einen Timer zum Senden auf PC Seite zu haben? Die Hardware hat doch eh eigene Sende- und Empfangspuffer. Kann man dort die zu versendenen Nachrichten nicht blockweise reinschieben und die HW sendet das mit dem eigenen Timer nach dem angegebenen Sendeintervallbei zyklischen Nachrichten? Grad bei den per USB angeschlossenen Boxen könnte man es doch sonst vergessen mit einigermaßen genauer Kommunikation, da ja auch USB lange nicht die Genauigkeit bietet die notwendig ist bei den verschiedenen Bussystemen.

Baka wa shinanakya naoranai.

Mein XING Profil.

N
191 Beiträge seit 2007
vor 12 Jahren

Also ich habe einen Prüfstand entwickelt, der auch per CAN-Bus am PC hängt.
Ich verwende dazu den IXXAT Adapter.
Vielleicht kann ich dir ja weiterhelfen, wenn ich mal dein Problem richtig kenne

"If you give someone a
program, you will frustrate them
for a day; if you teach them how to
program, you will frustrate them
for a lifetime." :evil: