0

我创建了一个计时器队列,但在我的代码第一次运行时,计时器并不可靠。然而,几分钟后,它就变成了正确的,即使是相当精确的。我附上超时。

50ms 周期

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 上创建的,这是我的代码:

主文件

#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);
}
4

0 回答 0