針對工控、即時資料擷取等需毫秒級甚至微秒級精度的場景,比較三種高精度計時方案,並示範如何產生固定頻率的週期性事件。
timeGetTimeWinmm.lib、包含 Mmsystem.h。DWORD start = timeGetTime();
while (timeGetTime() - start < 1000) { /* 1秒精確延遲 */ }
QueryPerformanceCounterLARGE_INTEGER 相減除以頻率得秒數。LARGE_INTEGER freq, start, now;
QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(&start);
do { QueryPerformanceCounter(&now); }
while ((double)(now.QuadPart - start.QuadPart) / freq.QuadPart < 0.001); // 1ms
timeSetEvent(週期性事件)timeBeginPeriod(1); // 設定 1ms 解析度
MMRESULT id = timeSetEvent(1, 1, TimerCallback, 0, TIME_PERIODIC);
// TimerCallback(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
// 執行週期性任務:資料採集、控制輸出...
timeKillEvent(id);
timeEndPeriod(1);
優點:系統自動排程,精度穩定。缺點:最小間隔 1ms,回呼執行時間必須 < 間隔。
QueryPerformanceCounter(突破 1ms 限制)UINT __stdcall TimerThread(LPVOID) {
LARGE_INTEGER freq, last, now;
QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(&last);
while (g_bRun) {
QueryPerformanceCounter(&now);
if ((double)(now.QuadPart - last.QuadPart) / freq.QuadPart >= g_interval) {
// 產生高頻事件
last = now;
}
// Sleep(0) 讓出時間片或忙等待
}
return 0;
}
Sleep(100) 實際誤差以 QueryPerformanceCounter 量測 Sleep(100) 實際耗時,發現誤差約 ±1~2ms,驗證高精度計時器必要性。