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