Alternativer Timer zu Sleep



  • Hallo Community,

    ich würde mir mit der Winapi gerne einen Sleeptimer erstellen der ein höhere Auflösung als Sleep besitzt. Der Faktor 10 würde mir schon reichen. Hat jemand eine Idee wie ich da vorgehen muss oder kann mir gar kein konkretes beispeil geben?



  • schau mal unter dem stichwort "multimedia timer" - insbesondere nach folgenden funktionen:

    timeBeginPeriod
    timeEndPeriod
    timeGetDevCaps
    timeGetSystemTime
    timeGetTime
    timeKillEvent
    TimeProc
    timeSetEvent
    


  • RockNix schrieb:

    schau mal unter dem stichwort "multimedia timer" - insbesondere nach folgenden funktionen:

    timeBeginPeriod
    timeEndPeriod
    timeGetDevCaps
    timeGetSystemTime
    timeGetTime
    timeKillEvent
    TimeProc
    timeSetEvent
    

    Diese Funktionen kenne ich, und benutze ich schon. Deren Auflösung endet aber generel bei 1ms.



  • Such mal nach QueryPerformanceCounter.



  • _matze schrieb:

    Such mal nach QueryPerformanceCounter.

    Ja danke, das war eine super Idee, da hab ich jetzt Sleeps im μ-Sekunden Bereich realisieren können.



  • Marius.. schrieb:

    _matze schrieb:

    Such mal nach QueryPerformanceCounter.

    Ja danke, das war eine super Idee, da hab ich jetzt Sleeps im μ-Sekunden Bereich realisieren können.

    Wie genau die dann letztlich sind, ist aber fraglich. Auf die μs genau wirst du das sicher nicht hinkriegen. Windows ist halt kein Echtzeitbetriebssystem. Das heißt, dass z.B. durch andere Prozesse, mit denen du dir den Prozessor teilen musst, ein Aufruf deiner Sleep-Funktion u.U. nicht genauso lange dauert wie der andere...



  • Mir gings letztlich darum, dass der User einstellen kann wieviele Threats pro Sekunde gestartet werde. Jetzt war mir aufgefallen, immer wenn ich 130 eingestellt habe -> Sleep(1000/130); hab ich letztendlich im Schnitt immer 142 Threads ausgeführt. Was wohl logisch ist da 1000/130 = 7.69.. ist und somit Sleep(7) ausgeführt wurde, was wiederum 142 Threads pro Sekunde entsprach. Also was nützt mir die ganze Einstellerei die ich dem User zur Verfügung stelle, wenn er im Schnitt ein unkorrektes Ergebinss erhält. Jetzt bekommt er genau das, was er per Dialog eingestellt hat. Im Endeffekt war das Ganze eine mehr oder weniger kosmetische Korrektur.



  • Ist das jetzt dein Ernst?



  • hustbaer schrieb:

    Ist das jetzt dein Ernst?

    Am Schluss der Threadausführungen erscheit eine kleine Statistik und es spielt eigentlich nur für die Auswertung eine Rolle.
    Und ja es ist mein Ernst, ich kann Leute die aus Bequemlichkeit oder Faulheit heraus, wieder besseren Wissen Dinge falsch machen nicht ausstehen. Wenn ich weiss dass ich mit meiner Arbeit 100% zufrieden bin, dann ist sichergestellt, dass andere es auch sind, meine Ansprüche sind eben hoch.



  • meine Ansprüche sind eben hoch

    Und dann machst du solche extremen Frickeleien? 😮



  • Marius.. schrieb:

    hustbaer schrieb:

    Ist das jetzt dein Ernst?

    Am Schluss der Threadausführungen erscheit eine kleine Statistik und es spielt eigentlich nur für die Auswertung eine Rolle.
    Und ja es ist mein Ernst, ich kann Leute die aus Bequemlichkeit oder Faulheit heraus, wieder besseren Wissen Dinge falsch machen nicht ausstehen. Wenn ich weiss dass ich mit meiner Arbeit 100% zufrieden bin, dann ist sichergestellt, dass andere es auch sind, meine Ansprüche sind eben hoch.

    dann machs doch einfach richtig. vom user hast du eine variable threadsPerSec und immer, wenn du dran bist, schaust du wieviel zeit vergangen ist und startest so viele threads, wie nötig sind.

    im prinzip so:

    {
       int threads=0;
       time_t start=time(0);
       for(;;)
       {
          Sleep(rnd()%200);
          while(threads<(time()-start)*threadsPerSec)
          {
             startNewThread();
             ++threads;
          }
       }
    }
    

    nur noch ne feinere uhr als time() nehmen und fertig ist der lack.
    das startet dir wenn der user 543 threads pro sekunde haben will auch 543 threads pro sekunde. wenn der rechner mal ruckelt, werden starts einfach nachgeholt, auf lange sicht sinds einfach 543.



  • volkard schrieb:

    Sleep(rnd()%200);
    

    Auch eine gute Idee, dank für die Anregung. Aber für was soll obiger Teil deines Codes gut sein?



  • Marius.. schrieb:

    volkard schrieb:

    Sleep(rnd()%200);
    

    Auch eine gute Idee, dank für die Anregung.

    war nur zur verdeutlichung, daß es auch funktioniert, wenn Sleep(7) recht ungenau sleept, wie es ja manchmal der fall ist.

    Marius.. schrieb:

    Aber für was soll obiger Teil deines Codes gut sein?

    das war der ausgleich, der einfach so viele threads startet, wie nötig sind, um den schnott von threadsPerSec threads per sekunde zu halten.



  • Ist das ne Benchmark oder was?
    Ich zweifle die sinnhaftigkeit eines Parameters welches sich "Threads per Second" nennt allgemein an.
    Für Programme verwendet man normalerweise Thread-Pools o.ä., die eine fixe grösse haben. Und selbst wenn man die grösse des Pools dynamisch anpasst, sehe ich keinen Grund, ein "Threads per Second" Parameter zu haben.



  • Ich kenne die Internetverbindungsgeschwindigkeit der User nicht. Die aufgerufenen Funktionen sammeln Daten aus dem Internet, daher hat der User die Möglichkeit, durch einige Probeläufe festzustellen, welcher Wert für ihn am sinnvollsten ist. Daher war es notwendig diesen Wert variable zu gestalten. Nenn den Wert einfach "Connections per Second", wenn dich "Threads per Second" störrt.
    🙂



  • Hm.
    Ich bezweifle auch dass Connections-per-Second ein sinnvoller Parameter ist.
    Aber selbst wenn, dann würde ich eher nicht pro Connection einen eigenen Thread erstellen, sondern wie erwähnt, einen Thread-Pool verwenden.

    Wie wäre es mit folgenden Parametern:
    * max. open connections
    * max. half-open connections

    Also z.B. es dürfen maximal 500 Connections gleichzeitig offen sein (vollständig verbunden), und maximal 50 Connections gleichzeitig "halb offen" sein (halb offen sind sie während connect() ausgeführt wird).

    Das lässt sich dann ganz ohne Timer, einfach mit ein oder zwei Condition-Variablen und einem Thread-Pool lösen.
    Die nötige Grösse des Pools ist dabei auch leicht zu ermitteln: einfach die max. erlaubte Anzahl an (vollständig) offenen Verbindungen.

    Was hältst du davon?

    p.S.: ein Parameter für "max. half-open connections" ist IMO schonmal deswegen gut, weil Windows XP genau das auf 10 limitiert. Wenn du unter Windows XP über längere Zeit mehr als 10 halb offene Connections hast, dann wirst du irgendwann Timeouts bekommen. Bzw. wenn du versuchst pro Sekunde z.B. 150 Connections zu erstellen, wirst du (bei einer langsamen Verbindung, oder langsamen Servern zu denen du connecten willst) ganz schnell einige hundert "halb offene" Connections haben. Und wenn du pro Connection einen Thread verwendest, dann wird's dich bei 2000 Connections (= 2000 Threads) auf die Schnauze hauen (auf einem 32 Bit System, mit Default Stack-Grösse von 1MB).



  • Jede Connection ist für Sekundenbruchteile offen, dann sind die paar Bytes Daten da und sie wird wieder geschlossen. Ein paar Bytes kann in dem Fall 100 - 10000 bedeuten. Im schlimmsten Fall muss ich so 50000 Connections aufbauen. Wenn zu viel Threads gestartet werden, dann kann der Client nicht die Menge an Daten empfangen die die Server gerade schicken, weil die Internetverbindung des Users der Flaschenhals ist. Starte ich hingegen zu wenige Threads, dann dauert die Abfrage entsprechend lange, daher auch die Frickelei um möglichst genaue Werte einstellen zu können. Die Connections sind übrigens UDP und keine TCP Connections. Wie auch immer es läuft ja soweit zufriedenstellend, vergleichbare Programme sind zumeist langsamer, einige wenige bieten augenscheinlich ähnlich hohe Geschwindigkeiten, daher bin ich mit dem Ergebniss soweit zufrieden.



  • Er.
    Wenn es UDP ist, und du das vernünftig programmierst, brauchst du 1) garkeine Threads und 2) garkeine Parameter um optimale Performance zu bekommen 🙂
    *duck und weg*


  • Mod

    Marius.. schrieb:

    Jede Connection ist für Sekundenbruchteile offen, dann sind die paar Bytes Daten da und sie wird wieder geschlossen. Ein paar Bytes kann in dem Fall 100 - 10000 bedeuten.

    Und was soll diese Anzahl an Threads dann? Das ist eher hinderlich als produktiv...
    Zu dem würde ich mal dem nach gehen was hustbaer in seiner letzten Antwort geschrieben hat 😉



  • Ok, z.Z. siehst es so aus: mein Programm startet einen Thread der nur dafür zuständig ist alle Connection-Threads zu starten.

    Connection Thread sieht dann so aus:
    - starte Anfrage
    - warte auf Antwort (mit Timeoutzeit)
    - werte Antwort aus

    Das hiese jetzt nach euren Vorschlägen ich bräuchte nur noch einen Starter Thread der die Funktionen direkt aufruft. Aber wie sieht es dann mit der Timeoutzeit aus? Da müsste doch zumindest noch irgendwo ein Thread gestartet werden der nur für den Empfang der Daten aller Connections zuständig ist, oder liege ich da falsch? Dummerweise können die Daten auch über mehrere Pakete und in wahloser Reihenfolge eintreffen. Diese Auswertung ist z.Z. jetzt in jedem Thread also geschlossene Funktion realisiert. Ich hab da jetzt ein Verständnissproblem. Vieleicht könnt ihr mir die erforderlichen Ablaufschritte mal aufzeigen.


Log in to reply