Thread mit Timer



  • ich fass mal zusammen wie ich das verstanden hab:
    - im Konstruktor wird die Taktfrequenz der CPU ermittelt und die Adresse dieses Werts in dem Zeiger lpFrequency gespeichert. Ausserdem wird die Priorität des Threads erhöht (tpHighest)
    - in der Methode Execute wird der aktuelle Stand (Takt)der CPU abgefragt und die Adresse davon im Zeiger alt gespeichert, die while Schleife führt den im Block stehenden Code solange aus bis die Eigenschaft Terminated auf true gesetzt wird. Dabei wird wieder der aktuelle CPU-Takt aufgenommen und in der Variable neu gespeichert. In der if-Abfrage wird geprüft ob die gemessene Zeit (Differenz alt, neu geteilt durch die Frequenz) größer oder gleich 0.1 * i ist.
    wenn nicht wartet die CPU eine Sekunde.

    Das versteh ich jetzt nicht mit dem Timer. Die angegebene Hilfe bringt mir da leider auch nichts, da es dort anders gemacht wurde.



  • Hallo

    Ich hab erstmal den Link in meinem letzten Post korrigiert, der hat gefehlt.

    Was verstehst du nicht an Thread? Falls es noch um Synchronize geht :
    1. Du darfst aus einem Thread normalerweise heraus nicht auf Speicher zugreifen, der nicht zu dem Thread gehört. Dazu gehören auch alle GUI-Komponenten
    2. Also werden alle GUI-Zugriffe in eine extra Methode ausgelagert, bei dir UpdateCaption
    3. Diese Funktion darf aber nicht direkt von TThread::Execute aus aufgerufen werden, sondern muß als Funktionszeiger an die Methode Synchronize übergeben werden.
    4. Synchronize sorgt dafür, das vor dem Ausrühren von UpdateCaption erst der Thread mit dem GUI-Thread synchroniziert wird. Dann ist der Zugriff innerhalb von UpdateCaption auf GUI-Komponenten erlaubt.

    bis bald
    akari



  • ok das hab ich dann denk ich kapiert, dh. ich muss alles was mit der GUI zu tun hat, ZB Ausgabe eines Messwerts auf ein Label, in eine extra Funktion schreiben, hier UpdateCaption. Der primäre Thread wird also während der Ausführung vorübergehend angehalten. ok, das ist klar.

    Was soll dann aber die Zeile:

    if((neu-alt)/(double)lpFrequency >= (0.1*i)){
    

    Versteh den zusammenhang mit dem Timer nicht 😞

    den Code hatte ich von einem Kollegen.
    Es geht am Ende darum einene Messwert auszulesen, der von einem Sensor kommt. Das alles soll in einem Thread verpackt werden. Die Ansteuerung des Sensors sowie die Einstellung der verschiedenen Parameter dieses Sensors funktioniert bereits.



  • Hallo

    Ist doch eigentlich eine nachvollziehbare Berechnung :
    Mit QueryPerformanceFrequency wird vom Betriebssystem der aktuelle Zeitstempel geholt und in neu gespeichert. Aus der Differenz zu alt (dem ersten Zeitstempel, bei dem etwas ausgegeben wurde) ergibt sich der Zeitraum, der seit der letzten Aktualisierung der GUI vergangen ist. Dieser wird nun in (Milli-) Sekunden umgerechnet und dann mit der eingestellten Frequenz verglichen. Ist ein Frequenz-Intervall vorbei, wird die GUI aktualisiert.

    Anmerkungen :
    - Das i, lpFrequency, alt, neu offenbar globale Variablen sind, ist äußerst schlecht. Es sollten Member-Variablen deiner Thread-Klasse sein

    bis bald
    akari



  • Außerdem mußt du für die Zeile

    Form1->lAnzeige->Caption = "beendet";
    

    auch den Synchronize-Mechanismus benutzen.

    Desweiteren ist es schlecht, daß du direkt auf Form1 und dessen Controls zugreifst - so koppelst du den Thread zu stark an die Form1.



  • wie macht man das denn anders bzw besser? mir wurde es so gezeigt



  • Hallo

    Du erstellst eine zweite Update-Methoden und verlegst den "beendet"-Aufruf darein.
    In der Execute-Methode rufst du dann Synchronize mit dieser zweiten Update-Methode auf

    bis bald
    akari



  • Ein sleep(1) kehrt nicht nach 1 ms wie erwartet zurück! Meistens viel später, weil die Windows-API das gleiche Problem mit den Ungenauigkeiten hat. Du kannst ja spassenshalber einmal 500 mal messen wie lange denn das sleep(1) gedauert hat. Es ist enttäuschend!

    MfG



  • Ich habe mal die Sleep-Funktionen getestet und dabei folgendes Kurioses festgestellt:

    Sleep(n) | Anzahl/Sekunde (Durchschnitt über mehrere Sekunden)
    --------------------------------------------------------------
          0  | ca. 800.000
          1  | 500
          2  | 333
          3  | 250
          4  | 200
          5  | 167
         10  |  91
        100  |   9.9
    

    Wie man sieht, scheint der Sleep() intern um 1 ms höher zu sein, als man angegeben hat (nur bei 0 ist es korrekt)!



  • Ich glaube eher, dass der Rest deines funktionalen Codes die 'fehlenden' Counts erklärt.

    Gruß KK


Anmelden zum Antworten