Windows 核心编程内核对象同步之-Waitable timer

来源:互联网 发布:凡客建站seo 编辑:程序博客网 时间:2024/05/17 06:13

基本函数介绍:


创建定时器

  1. HANDLE WINAPI CreateWaitableTimer(
  2.   __in_opt  LPSECURITY_ATTRIBUTES psa,
  3.   __in      BOOL bManualReset,
  4.   __in_opt  LPCTSTR lpTimerName
  5. );

参数1:此参数在Vista下,如果跨Session通信的话注意权限和完整性问题

参数2:创建的是手动重置的等待定时器还是自动重置的等待定时器

参数3:内核对象的名称,类似如Gloable/AA 或者AA的形式


刚创建的时候,等待定时器的状态总是没有触发的状态,需要调用 SetWaitableTimer函数触发


获得一个已经创建的等待定时器的句柄根据名称来访问

  1. HANDLE WINAPI OpenWaitableTimer(
  2.   __in  DWORD dwDesiredAccess,
  3.   __in  BOOL bInheritHandle,
  4.   __in  LPCTSTR lpTimerName
  5. );

设置定时器

  1. BOOL WINAPI SetWaitableTimer(
  2.   __in      HANDLE hTimer,
  3.   __in      const LARGE_INTEGER *pDueTime,
  4.   __in      LONG lPeriod,
  5.   __in_opt  PTIMERAPCROUTINE pfnCompletionRoutine,
  6.   __in_opt  LPVOID lpArgToCompletionRoutine,
  7.   __in      BOOL fResume
  8. );

参数1:需要触犯的等待定时器的句柄

参数2

参数323参数一起使用,DueTime 表示的是第一次触发的时间,而period表示的是第一次触发之后,定时器调度的频度(即多久之后再次触发)

参数4:定时器被触发的时候的APC函数地址,此APC例程只有当Set函数的调用线程正处于 alterable state的时候,此函数才会被set函数的同一个线程所调用

参数5:传送给参数4的函数的参数


Note:参数2的类型是 LARGE_INTEGER 不能直接的接受SYSTEMTIME结构类型,尽管他们的结构一致,但是LARGE_INTEGER64位对齐,而SYSTEMTIME32位对齐

可以做如下的转换:

FILETIME ftFileTime;

LARGE_INTEGER liTime;

liTime.LowPart = ftFileTime.dwLowDateTime;

liTime.QuardPart = ftFileTime.dwHighDateTime;

另外次函数传入的时间默认的是UTC时间

第一次触发的时间可以是个绝对时间也可以是个相对时间,只需pDueTime传入负值

例如如下代码:

  1. HANDLE hTimer =INVALID_HANDLE_VALUE;
  2. LARGE_INTEGER liDueTime = {0};
  3. hTimer = CreateWaitableTimer(NULL, FALSE, NULL);
  4. if(hTimer == INVALID_HANDLE_VALUE)
  5. {
  6.     return -1;
  7. }
  8. const int iTimerUnitPerSecond = 1000000;
  9. liDueTime.LowPart = -(5*iTimerUnitPerSecond);
  10. SetWaitableTimer(hTimer, liDueTime, lPeriod, NULL, NULL, FALSE);

取消等待定时器

  1. BOOL WINAPI CancelWaitableTimer(
  2.   __in  HANDLE hTimer
  3. );
Note:关于TimerAPC例程,函数必须保证 APC Route函数必须在下次Timer被再次触发之前结束,
否则APC函数加入队列的速度超过了处理他们的速度,APC例程将会一直被执行
  1. VOID APIENTRY TimerFunction(PVOID pvArg, DWORD dwLowPart, DWORD dwHighPart)
  2. {
  3.     FILETIME ftUTC, ftLocal;
  4.     SYSTEMTIME st;
  5.     TCHAR tszBuf[MAX_PATH]= {0x00};
  6.     ftUTC.dwLowDateTime = dwLowPart;
  7.     ftUTC.dwHighDateTime = dwHighPart;
  8.     FileTimeToLocalFileTime(&ftUTC, &ftLocal);
  9.     FileTimeToSystemTime(&ftLocal, &st);
  10.     GetDateFormat(LOCALE_USER_DEFAULT, 0,&st, NULL,
  11.         _tcschr(tszBuf, TEXT('/0')), 
  12.         (int)(_countof(tszBuf) - _tcslen(tszBuf)));
  13.     _tprintf(TEXT("Timer Went OK.../n"));
  14.     Sleep(2000);
  15. }
  16. VOID TimerTest()
  17. {
  18.    HANDLE hTimer = INVALID_HANDLE_VALUE;
  19.     hTimer = CreateWaitableTimer(NULL, FALSE, NULL);
  20.     if(hTimer == INVALID_HANDLE_VALUE)
  21.     {
  22.         return ;
  23.     }
  24.     LARGE_INTEGER liTime = {0};
  25.     SetWaitableTimer(hTimer, &liTime, 5000, 
  26.                          TimerFunction, NULL, FALSE);
  27.     SleepEx(INFINITE, TRUE);
  28.     CloseHandle(hTimer);
  29. }
  30. int _tmain(int argc, _TCHAR* argv[])
  31. {
  32.     TimerTest();
  33.     return 0;
  34. }
 
 
 
原创粉丝点击