你可以使用一个计时器事件。如果你需要一个非常坚固的时钟,你需要提高你的优先级到最大。此代码将为您提供用户模式应用程序的最佳性能。为了清楚起见,我省略了通常的错误检查,但是我标记了应该检查的调用。如有疑问,请咨询MSDN。
的Windows计时器的分辨率被限制在一个全球性的时间片Windows使用线程之间进行切换。在现代CPU上,这个值通常为2-5ms。在较旧的CPU上,这个值是10-15ms。您可以通过调用timeBeginPeriod()来控制此全局设置 。这会影响中断的精度。
// use this event to exit the loop, by calling SetEvent(hExitEvent).
HANDLE hExitEvent = CreateEvent(NULL, NULL, FALSE, NULL);
void RealTimeLoop()
{
// You may want to raise the process priority...
HANDLE hProcess = GetCurrentProcess(); // never fails
SetPriorityClass(hProcess, REALTIME_PRIORITY_CLASS);
// setting the priority is critical.
HANDLE hThread = GetCurrentThread(); // never fails
SetThreadPriority(hThread, THREAD_PRIORITY_TIME_CRITICAL); // could fail
timeBeginPeriod(1); // could fail
HANDLE hTimer = CreateWaitableTimer(NULL, FALSE, NULL); // could fail
// could also set a call back here, but I've never tried it.
LARGE_INTEGER dueTime = {};
SetWaitableTimer(hTimer, &dueTime, 20, NULL, NULL, FALSE); // could fail
HANDLE ah[2] = { hExitEvent, hTimer };
bool exitLoop = false;
while(!exitLoop)
{
switch (WaitForMultipleObjects(2, ah, FALSE, INFINITE))
{
default: // error would arrive here
case 0: exitLoop = true; break;
case 1: ExecuteMethod(); break;
}
}
timeEndPeriod(1);
CloseHandle(hTimer);
CloseHandle(hThread);
CloseHandle(hProcess);
}
您正在使用重复的相对时间,这会在确定实际循环时间和设置所需循环时间之间容易受到竞速条件的影响。您需要一个具有所需周期时间的外部控制的周期性触发器。 – Yunnosch
您可能想要查看https://stackoverflow.com/questions/2904887/sub-millisecond-precision-timing-in-c-or-c/2905082#2905082 – jodag
timeSetEvent与timeBeginPeriod一起使用时相当可靠。 MSDN说它已经过时,但你应该使用https://msdn.microsoft.com/en-us/library/ms682485(v=vs.85).aspx我没有任何经验,所以我不能说它有多可靠或精确。 –