你可以使用一個計時器事件。如果你需要一個非常堅固的時鐘,你需要提高你的優先級到最大。此代碼將爲您提供用戶模式應用程序的最佳性能。爲了清楚起見,我省略了通常的錯誤檢查,但是我標記了應該檢查的調用。如有疑問,請諮詢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我沒有任何經驗,所以我不能說它有多可靠或精確。 –