C > windows下定時器(非阻塞方式定時調用自定義處理函數)


time(), clock(), gettimeofday()等庫函數需要2次查詢當前時間點,比較差值,才能判斷經過多少時間。也就是說如果需要在1S后觸發一個動作,就需要延時等待,而且要一直保持查詢,這樣就屬於阻塞方式了,會浪費大量CPU時間。

 

對於非阻塞方式,Linux下有alarm和setitime定時調用任務處理函數,可是Windows下要如何用非阻塞方式定時回調任務處理函數呢?

可以使用Windows API timeSetEvent(). 本文介紹如何在Win10x64專業版 + eclipse photon + CDT + MinGW環境下, 設置非阻塞方式的定時調用自定義任務處理函數,以達到周期性調用目的。

使用timeSetEvent 需要引入"WinMM.Lib"。

 

eclipse + CDT + MinGW C Linker引入方法:
1)檢查庫文件WinMM.Lib及路徑
檢查路徑下是否包含該lib文件,如果不包含需要重新下載,並放入推薦的默認路徑(路徑非必須按默認設置)。
文件默認路徑是
C:\Program Files (x86)\Microsoft SDKs\Windows\v6.0A\bin\WinMM.Lib
 
推薦一個下載鏈接:
http://www.opdown.com/soft/125224.html
 
2)eclipse鏈接WiMM.lib庫
右鍵eclipse工程 屬性->C/C++ Build -> Settings -> MinGW C Linker -> Libraries,Library search path (-L)添加路徑,Libraries (-I) 添加文件(注意不要帶后綴名.lib,不然會報錯"ld.exe: cannot find -lWinMM.lib
 
 
3)工程代碼配置
工程中無需使用預編譯指令 #pragma comment (lib,"WinMM.Lib")。這點與VS平台不一樣。
 
4)代碼編寫
#include <windows.h>

static int cnt = 0;
void CALLBACK onTimeFunc(UINT wTimerID,UINT msg, DWORD dwUser,DWORD  dw1,DWORD dw2)
{
      cnt ++;
      time_t nowtime;
      time(&nowtime);
      char *p = ctime(&nowtime);
      printf("%s", p);
      fflush(stdout); // 強制刷新流 stream 的輸出緩沖區
}

int main()
{
      MMRESULT timer_id = timeSetEvent(
                  1000, // 以毫秒指定事件的周期
                  1, // 精度, 默認1ms
                  &onTimeFunc, // 回調函數地址
                  (DWORD)1, // 存放用戶提供的回調數據
                  TIME_PERIODIC); // TIME_ONESHOT -- 執行一次;  TIME_PERIODIC -- 周期性執行;
      if(!timer_id)
      {
            printf("timeSetEvent() failed with error %ld \n ",  GetLastError());
            return -1;
      }
      while(cnt < 10)
      {
            Sleep(100); // 睡眠, 精度1ms
      }
      timeKillEvent(timer_id); // 釋放定時器
      return EXIT_SUCCESS;
}

 

輸出 

Sun Apr 26 16:24:54 2020
Sun Apr 26 16:24:55 2020
Sun Apr 26 16:24:56 2020
Sun Apr 26 16:24:57 2020
Sun Apr 26 16:24:58 2020
Sun Apr 26 16:24:59 2020
Sun Apr 26 16:25:00 2020
Sun Apr 26 16:25:01 2020
Sun Apr 26 16:25:02 2020
Sun Apr 26 16:25:03 2020

 

REF: 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM