Очереди таймера - приложения Win32 - проблема тайм-аута - PullRequest
0 голосов
/ 08 апреля 2020

Я создал очередь таймера, но при первых запусках моего кода таймер ненадежен. Однако через несколько минут он становится правильным даже с разумной точностью. Я прилагаю тайм-ауты.

период 50 мс

47 47 60 46 47 63 46 46 47 49 63 47 47 47 60 46 47 63 46 46 47 49 63 47

после нескольких минут выполнения периода 50 мс

50 50 50 50 50 50 50 49 50 50 49 49 50 49 50 49 49 50 50 с таймером синхронизируется также при следующих выполнениях кода, таймер надежен. Но если я не запускаю код в течение часа (например), проблема повторяется.

Кто-нибудь знает причину этой проблемы? Как мне получить точный и надежный таймер с первого запуска?

Этот таймер создан на std :: thread, вот мой код:

main. cpp

#include "NativeTimer.h"
#include <windows.h>
#include <iostream>

static int times0;
VOID func(PVOID lpParam, BOOLEAN TimerOrWaitFired)
{
    times0 = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count() - times0;
    std::cout << times0 << std::endl;
    times0 = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
}
int main()
{
    NativeTimer *t1 = new NativeTimer(50,func);
    while(1)
    {}
}

NativeTimer.h

#ifndef NATIVETIMER_H
#define NATIVETIMER_H

#include <windows.h>
#include <thread>

class NativeTimer
{
public:
    NativeTimer(unsigned int msec,
                VOID (*func)(PVOID lpParam, BOOLEAN TimerOrWaitFired));
public:
    void stopTimer();
private:
    int startTimer(unsigned int msec,
                VOID (*func)(PVOID lpParam, BOOLEAN TimerOrWaitFired));
    int _id;
    unsigned int _msec;
    std::thread _thread;
    HANDLE gDoneEvent;
};

#endif // NATIVETIMER_H

NativeTimer. cpp

#include "NativeTimer.h"
#include <iostream>


NativeTimer::NativeTimer(unsigned int msec,
                         VOID (CALLBACK *func)(PVOID lpParam, BOOLEAN TimerOrWaitFired))
{
    _thread = std::thread(&NativeTimer::startTimer, this, msec, func);
}


int NativeTimer::startTimer(unsigned int msec,
                            VOID (CALLBACK *func)(PVOID lpParam, BOOLEAN TimerOrWaitFired))
{
    HANDLE hTimer = nullptr;
    HANDLE hTimerQueue = nullptr;

    gDoneEvent = CreateEvent(nullptr, TRUE, FALSE, nullptr);

    hTimerQueue = CreateTimerQueue();

    CreateTimerQueueTimer( &hTimer,
                           hTimerQueue,
                           (WAITORTIMERCALLBACK)func,
                           nullptr,
                           msec,
                           msec,
                           0);

    if (WaitForSingleObject(gDoneEvent, INFINITE) != WAIT_OBJECT_0)
        printf("WaitForSingleObject failed (%d)\n", GetLastError());

    CloseHandle(gDoneEvent);
    DeleteTimerQueue(hTimerQueue);

    return 0;
}

void NativeTimer::stopTimer()
{
    SetEvent(gDoneEvent);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...