首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

Windows 高精度計時與高頻事件產生:timeGetTime、QueryPerformanceCounter 多媒體定時器與多執行緒輪詢法

     編輯:關於VC++

針對工控、即時資料擷取等需毫秒級甚至微秒級精度的場景,比較三種高精度計時方案,並示範如何產生固定頻率的週期性事件。

方案一:多媒體定時器 timeGetTime

  • 回傳開機以來毫秒數(DWORD),最大 49.7 天歸零。
  • 優先權高,精度約 1ms,適合一般高精度需求。
  • 需連結 Winmm.lib、包含 Mmsystem.h。
DWORD start = timeGetTime();
while (timeGetTime() - start < 1000) { /* 1秒精確延遲 */ }

方案二:硬體效能計數器 QueryPerformanceCounter

  • 頻率可達 MHz 級(筆者測試 3.57 MHz),理論精度亞微秒。
  • 雙 LARGE_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;
}
  • 可產生 < 1ms 間隔事件(理論上限為硬體計數器頻率)。
  • 缺點:執行緒調度延遲可能導致事件遺漏,頻率越高遺漏機率越大。
  • 適合產生高頻隨機訊號、即時模擬而非硬性控制迴路。

測試 Sleep(100) 實際誤差

以 QueryPerformanceCounter 量測 Sleep(100) 實際耗時,發現誤差約 ±1~2ms,驗證高精度計時器必要性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved