Tread GENAU 1 Millisekunde warten lassen, wie ?



  • Hallö'chen,
    Ich hab hier mal wieder ein kleines Problem und zwar brauche ich in meinem Programm einen Thread der Millisekunden genau "tickt". Das Problem was sich mir jetzt aber auftut ist folgendes, wenn ich versuche die Schleife in dem Thread zu pausieren mit Sleep( 1 ), wird der Timer der hoch gezählt wird, nicht schnell genug hoch gezählt. Sprich ich habe mal den Thread, also den Timer zeitgleich mit der Windoofuhr laufen lassen, schon nach 15Sekunden fällt auf, dass mein Timer nlangsamer läuft al die Uhr. Demnach heißt es also, dass Sleep( 1 ) meinen Thread mehrnals nur 1ms ausbremst. Wobei dies sicher auch abhängig ist von dem jeweiligem Rechner wo das Programm läuft, oder?
    Meine frage ist jetzt also, gibt es noch weitere Möglichkeiten, eien Thread exakt n-viele ms zu stopen?, wobei das falsch vormuliert ist, es soll net der Thread gestoppt werden, sondern die Schleife in ihm.
    Die maximale Pausen-Toleranz sollte nicht mehr als 100ms betragen.

    Hoffe ihr könnt mir da helfen.

    Gruß Tobi.



  • Windows ist kein Echtzeit BS. Warum nimmst du nicht einfach die Systemuhr oder die Clockticks anstatt nen Counter hochzuzählen?



  • T0bi schrieb:

    Die maximale Pausen-Toleranz sollte nicht mehr als 100ms betragen.

    Um garantierte Zeiten zu haben, bräuchtest du ein Echtzeit-Betriebssystem. Auf einem normalen Windows, Mac OS X oder Linux wirst du es nie schaffen, einen Thread eine so exakte Zeit warten zu lassen.

    Vielleicht reicht aber schon, wenn du dein Design überdenkst. Ein Thread kann sich schlafen legen mit Sleep(1), wie du es jetzt schon machst, aber anstelle sich darauf zu verlassen, dass er nach exakt 1ms wieder aufwachst, fragt er nach dem Aufwachen halt die aktuelle Systemzeit ab.

    Übrigens sollte dir bewusst sein, dass ein Thread immer und zu jeder Zeit unterbrochen werden kann, auch ohne Sleep-Aufruf.



  • Übrigens ist die Auflösung unter windows xp und ähnlichem ca 15ms.
    Da wird kann ein Sleep(1) zu 0ms oder zu 15ms werden.

    Simon



  • So gehts:

    // ***** Sleep 5ms *****
            SYSTEMTIME sysTimeStart, sysTimeEnd;
    
            GetSystemTime( &sysTimeStart );
            do {
    
                memset( &sysTimeEnd, 0, sizeof( SYSTEMTIME ) );
                GetSystemTime( &sysTimeEnd );
    
            } while( ( ( sysTimeEnd.wHour * 60 * 60 * 1000 )   + ( sysTimeEnd.wMinute * 60 * 1000 )   + ( sysTimeEnd.wSecond * 1000 )   + sysTimeEnd.wMilliseconds ) < 
                     ( ( sysTimeStart.wHour * 60 * 60 * 1000 ) + ( sysTimeStart.wMinute * 60 * 1000 ) + ( sysTimeStart.wSecond * 1000 ) + sysTimeStart.wMilliseconds + 5 ) );
    
            lCounter += 5;
    

    Danke nochmal.

    Gruß Tobi.



  • rofl wie schlecht, das geht viel einfacher



  • Nimm besser GetTickCount



  • Nimm besser QueryPerformanceCounter



  • @T0bi: timeBeginPeriod + timeGetTime sollte einfacher sein. Reicht für 5ms Auflösung auch.



  • GetTickCount hab ich auch shcon versucht, doch irgendwie spinnt das manchmal nen bissel rum, außdem wurde mir Systemtime empfohlen und ich habs benutzt und nun kommt ihr Klugscheißer an und meint es geht noch einfacher xD, rückt doch gleich mit der Antwort raus *g*
    Ich lass das jetzt so, so gehts jedenfalls .



  • und was ist wenn jemand zwischen den aufrufen die systemzeit zurückstellt?



  • Genau so ganz rein zufällig, gell?

    Und was ist, wenn ich timeGetTime ect. benutze und ganz rein zufällig 49.71Tage vergangen sind und alles auf 0 zurück gesetzt wird?



  • Und was ist, wenn ich timeGetTime ect. benutze und ganz rein zufällig 49.71Tage vergangen sind und alles auf 0 zurück gesetzt wird?

    wenn mans richtig macht, gibts da keine probleme





  • Auf die Gefahr hin, dass du unbelehrbar bist:

    (1) Um auf 1ms warten zu können, brauchst du eine Uhr, die deutlich genauer als 1 ms auflöst. Zum Beispiel wenn du eine Uhr hast, die 3mal in 2ms tickt, wie willst du dann eine ms warten können? Die genaueste Uhr unter Windows ist der PerformanceCounter und im ms-Bereich würde ich den schon hernehmen. Weiterhin ist der Counter nicht zyklisch (außer nach ein paar Millionen Jahren) und du hast die damit verbundenen Probleme nicht.

    (2) Du kannst nur mindestens 1 ms warten, ob das OS dich dann rechnen lässt, darauf hast du keinen Einfluss. 1 ms ist für ein Nicht-RT-OS schon schwierig, da eine Zeitscheibe normal so um die 10ms beträgt [1, 2]. Das heißt, wenn ein anderer Prozess rechnen will, kommst du 10ms oder länger mal einfach gar nicht dran.

    (3) Rechne in deinem Programm damit, dass die 1ms nicht immer eingehalten wird und reagiere vernünftig darauf.

    [1] http://widefox.pbwiki.com/Scheduler
    [2] http://technet.microsoft.com/en-us/magazine/cc162494.aspx


Anmelden zum Antworten