Timer / Zeitsteuerung



  • hustbaer schrieb:

    Er meinte bei Verwendung eines Timers ohne zusätzlichem Thread steht die Hauptschleife *während du das File neu ausliest*.
    Deswegen hab' ich auf gefragt wie lange das dauert.
    Während der "Wartezeit" steht die Hauptschleife natürlich nicht.

    Grossartig! So hatte ich's jetzt auch verstanden. Das parallele Auslesen sehe ich mir dann 2009 an :).



  • So, jetzt steh ich aber wieder auf dem Schlauch.
    Ich hatt mir die Funktion 'SetTimer' herausgesucht. Aber anscheinend funktioniert die nur ordentlich, wenn man ein Fenster hat. Was mache ich denn, wenn ich keine habe?
    Muß ich dann andere Klassen benutzen?

    Sry, falls ich etwas übersehen habe. Ist wohl schon zu spät....



  • msdn schrieb:

    UINT SetTimer( HWND hWnd, UINT nIDEvent, UINT uElapse, TIMERPROC pTimerFunc );

    hWnd: Handle to the window to be associated with the timer. This window must be owned by the calling thread. If this parameter is NULL, no window is associated with the timer and the nIDEvent parameter is ignored.

    nIDEvent: Specifies a nonzero timer identifier. If the hWnd parameter is NULL, this parameter is ignored.

    uElapse: Specifies the time-out value, in milliseconds.

    lpTimerFunc: [Long pointer to the function to be notified when the time-out value elapses. For more information about the function, see TimerProc.
    If lpTimerFunc is NULL, the system posts a WM_TIMER message to the application queue. The hwnd member of the message’s MSG structure contains the value of the hWnd parameter.

    msdn schrieb:

    void CALLBACK TimerProc( HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime );

    hwnd: [in] Handle to the window associated with the timer. wird wahrscheinlich 0 sein

    uMsg: [in] Specifies the WM_TIMER message.

    idEvent: [in] Identifier of the timer. wird wahrscheinlich 0 sein

    dwTime: [in] Specifies the number of milliseconds that have elapsed since the system was started. This is the value returned by the GetTickCount function.

    Also geht auch ohne Fenster. Musst bei SetTimer für hWnd NULL einsetzen und lpTimerFunc muss auf eine Funktion zeigen, die wie oben deklariert ist 🤡



  • Das bekomme ich so recht nicht auf die Reihe. Auch nicht, durch Lesen der diversen Threads zu dem Thema:
    Diese Lösung habe ich gefunden und sie läuft:

    #include <windows.h>
    #include <iostream>
    
    void CALLBACK TimerProc (HWND hwnd, UINT message, UINT TimerID, DWORD dwTime)
    {
       std::cout << "hello timer" << std::endl;
    }
    
    int main()
    {
       SetTimer(NULL, 1, 1000,(TIMERPROC) TimerProc);
       MessageBox (NULL, "muss sein, sonst hat dein proggi keine message queue", "", MB_OK);
    }
    

    - Das ist MIT Fenster und MIT Callback, korrekt?

    Wie sähe die Lösung ohne Callback aus?

    Und wichtiger: wie die Funktion ohne Fenster? Ich bekomm's auch nicht hin eine Messagequeue selbst zu erstellen (was vielleicht auch an 'nebenbei liegt', s.u.).

    Nebenbei: Wenn ich in einer Loop auf den Timer warten muss, dann ist das etwas blöd, weil ich 'meine Main-Loop' bereits für das Update eines Peripheriegeräts brauche und das nur ungern vermischen möchte.

    ------

    Sry, falls ich mich blöd anstelle, hatte gehofft, dass etwas Schlaf hilft...



  • Die lösung ist ohne fenster (Hwnd NULL)!!

    die funktion :

    void CALLBACK TimerProc (HWND hwnd, UINT message, UINT TimerID, DWORD dwTime)
    {
       std::cout << "hello timer" << std::endl;
    }
    

    wird nun jede sekundne ausgeführt, darin kannst du deine datei lesen...



  • BorisDieKlinge schrieb:

    (Hwnd NULL)!!

    Ähhmmm.... das ist doch aber NULL!

    SetTimer([b]NULL[/b], 1, 1000,(TIMERPROC) TimerProc);
    

    Oder welches Handle ist gemeint?

    btw: seeeehr schnelle Antwort, wow - ich muss jetzt erstmal frühstücken, aber dann bin ich wieder da 😋



  • Erste Parameter von "SetTimer(HWND hWnd,.....)" -< wenn der NULL ist, dann OHNE Fenster... Die löung dürfe also für deine Ansprüche KORREKT sein



  • Hab grad keine Lust zu gucken, warum das mit der TimerProc nicht funktioniert (na gut, Message-Queue fehlt).
    Jedenfalls, Message-Queue geht so:

    MSG Msg;
    while ( GetMessage( &Msg, NULL, 0, 0 ) )
    {
        TranslateMessage( &Msg );
        DispatchMessage( &Msg );
    }
    

    Kommst aber halt so nicht aus der Message-Queue raus, ohne Fenster und so. Außer du benutzt PeekMessage statt GetMessage, baust eine Zeitabfrage rein und ein kleines Sleep.

    Eine andere Lösung ist timeSetEvent, da kannst du eine Menge Parameter angeben, z.B. brauchst du auch keinen Message-Queue.

    #include <mmsystem.h>
    #pragma comment( lib, "Winmm.lib" ) // oder die lib einfach so angeben
    
    void CALLBACK TimerProc( UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)
    {
    }
    
    ...
    
    MMRESULT r = timeSetEvent( 1000, 1, TimerProc, 0, TIME_PERIODIC|TIME_CALLBACK_FUNCTION|TIME_KILL_SYNCHRONOUS );
    ...
    timeKillEvent( r );
    


  • BorisDieKlinge schrieb:

    Erste Parameter von "SetTimer(HWND hWnd,.....)" -< wenn der NULL ist, dann OHNE Fenster... Die löung dürfe also für deine Ansprüche KORREKT sein

    Das habe ich doch aber probiert, mit meinem Bsp-Code, habe nur die MessageBox weggelassen. Aber dann bleibt die Konsole leer, keine Ausgaben.

    @badestarnd: das sehe ich mir nachher mal an.



  • MSDN - SetTimer schrieb:

    An application can process WM_TIMER messages by including a WM_TIMER case statement in the window procedure or by specifying a TimerProc callback function when creating the timer. When you specify a TimerProc callback function, the default window procedure calls the callback function when it processes WM_TIMER. Therefore, you need to dispatch messages in the calling thread, even when you use TimerProc instead of processing WM_TIMER.

    Auf gut Deutsch - SetTimer funktioniert nur auf Grundlage einer bestehenden Message-Queue (d.h. in einem WinAPI-Programm).



  • So, an dieser Stelle ersteinmal DANKE an alle, die mir helfen!

    ...und jetzt weiter im Text:
    SetTimer ist also nichts.
    timeSetEvent könnte klappen, das teste ich gleich mal. Laut MSDN läuft der Timer dann aber in einem eigenen Thread, wenn ich später mal das Aktualisieren meiner Daten in einem eigenen Thread machen möchte, dann wäre ich damit schon bei 3 Threads.... wäre es in em Fall dann sinnvoller, den 2 Thread zu starten in statt timeSetEvent einfach mit einem Sleep zu arbeiten? Oder ist Sleep inperformant?

    Eine ganz andere Variante ist an dieser Stelle ja das Arbeiten mit Timestamp (wie auch immer das genau aussieht), damit meine ich, ich definiere den Zeitpunkt der nächsten Aktualisierung und prüfe in meiner Schleife, ob die Systemzeit diesen Zeitpunkt überschritten hat (das Update also stattfinden muß).
    Wie sieht's damit aus? Gibt es Gründe (Performance), warum timeSetEvent vorzuziehen ist?



  • Im Prinzip ist es ziemlich egal, was du davon jetzt machst 🙂

    Von der Performance tut sich das alles nicht viel; während ein Thread schläft, verbraucht er absolut nüscht außer bissl Arbeitsspeicher, allerdings ist es natürlich schöner, weniger statt mehr Threads zu haben.

    Was du jetzt machst, bleibt allein dir überlassen. Wenn die Timestamp-Variante einfach und ungefährlich zu implementieren ist, würde ich das vorziehen; aber nur wenn. Ansonsten finde ich timeSetEvent die komfortabelste Methode 🤡

    Und bitte fürs helfen 🙂

    PS: Was du halt berücksichtigen musst, ist, dass die extra-Thread-Variante einen großen Vorteil hat: Sie bremst nix aus, falls die Festplatte grad langsam oder die Datei groß ist. Dann kann der Thread fröhlich vor sich hin werkeln, ohne dass irgendwas hängen bleibt.



  • So, nach dem ganzen Hin- und Her war ich jetzt doch auf Threads gespannt.
    Ich habe Beispiel-Code gefunden, der mit '_beginthread' (process.h) arbeitet.....
    dabei bin ich auch Fragen gestossen, die ich in einem neuen Thread gestellt habe:

    http://www.c-plusplus.net/forum/viewtopic-var-p-is-1318547.html#1318547


Anmelden zum Antworten