首页 > 代码库 > 线程同步——内核对象实现线程同步——可等待计时器内核对象

线程同步——内核对象实现线程同步——可等待计时器内核对象

  1 可等待计时器  2     可等待计时器是这样一种内核对象,他们会在某个指定的时间触发或每隔一段时间触发一次。  5     下面我们来介绍一下创建可等待计时器函数:  6   7     HANDLE CreateWaitableTimer(   8     LPSECURITY_ATTRIBUTES lpTimerAttributes,   9     BOOL bManualReset,  10     LPCSTR lpTimerName ); 11 第一、三个参数我想我也不用介绍了哈,这是创建内核对象基本都会有的参数。 12     第二个参数bManualReset表示是创建一个手动重置(TRUE),还是自动重置(FALSE)计时器。 13     有一点需要记住:创建可等待计时器总是处于未触发状态。必须调用SetWaitableTimer函数来告诉它。 14  15     BOOL SetWaitableTimer( 16     HANDLE hTimer,  17     const LARGE_INTEGER *lpDueTime, 18     LONG lPeriod,  19     PTIMERAPCROUTINE pfnCompletionRoutine, 20     LPVOID lpArgToCompletionRoutine, 21     BOOL fResume ); 22 第一参数hTimer表示我们要设置的计时器 23     第二个和第三个参数应该一起使用,lpDueTime表示第一次触发应该在什么时候, 24     lPeriod表示计时器应该以什么样的频度触发。第三个参数的单位是微秒 25     另外两个参数这里就先不介绍了,如果感兴趣可以阅读《windows核心编程(第五版)》245页 或者参考MSDN. 26     如果只是简单的应用,后面三个参数,依次填入 NULL,NULL,FALSE 即可,嘿嘿,简单吧! 27  28  29 特别注意: 30 如果该计时器是手动重置,则正在等待该线程的所有线程变为可调度,当该定时器是自动重置, 31 则只有一个等待该线程的计时器变为可调度。当定时器是自动重置时,每当WaitFor*Object  32 获得该对象时,会重新计时,而手动重置则不会重新计时,这点特别注意。 33  34 下面说一下使用步骤 35 1) 36 //定义一个定时器内核对象,还有一些关于时间的变量 37 HANDLE g_hTimer ;   38 SYSTEMTIME st; 39  40 FILETIME ftLocal,ftUTC; 41  42 LARGE_INTEGER liUTC ; 43 2 44 //创建一个自动重置的定时器内核对象 45 g_hTimer = CreateWaitableTimer(NULL,FALSE,NULL); 46  47 3)设置定时器内核对象,时间可以更根据自己的实际情况设定 48 //第一次响应是在 2014.08.10  在 17:12分 49  50 st.wYear = 2014 ; 51 st.wMonth = 8 ; 52 //st.wDayOfWeek = 0  //可以忽悠   53 st.wDay = 10 ; 54 st.wHour = 17 ; 55 st.wMinute = 12; 56 st.wSecond = 0 ; 57 st.wMilliseconds = 0 ; 58  59 SystemTimeToFileTime(&st,&ftLocal); 60  61 LocalFileTimeToFileTime(&ftLocal,&ftUTC) ; 62  63 liUTC.LowPart = ftUTC.dwLowDateTime ; 64 liUTC.HighPart = ftUTC.dwHighDateTime ; 65  66 //每隔1秒钟响应依次,记住,第三个单位是微妙,这里容易使人忘记。 67 SetWaitableTimer(g_hTimer,&liUTC,1000,NULL,NULL,FALSE); 68  69 4)在线程函数中调用 70 DWORD WINAPI ThreadFunOne(PVOID pvParam)  71 { 72     while(1) 73     { 74         WaitForSingleObject(g_hTimer,INFINITE); 75         g_x++; 76         cout<<"我是ThreadFunOne:"<<g_x<<endl; 77     } 78     return 0; 79 } 80  81  82  83 #include "windows.h" 84 #include "iostream" 85 using namespace std; 86 long g_x = 0 ; 87  88 //定义一个定时器内核对象,还有一些关于时间的变量 89 HANDLE g_hTimer ;   90 SYSTEMTIME st; 91  92 FILETIME ftLocal,ftUTC; 93  94 LARGE_INTEGER liUTC ; 95  96 //定义线程函数1 97 DWORD WINAPI ThreadFunOne(PVOID pvParam) ; 98  99 //定义线程函数2100 DWORD WINAPI ThreadFunTwo(PVOID pvParam);101 102 int main()103 {104 105     //创建一个自动重置的定时器内核对象106     g_hTimer = CreateWaitableTimer(NULL,FALSE,NULL);107 108     //第一次响应是在 2014.08.10  在 17:12分109 110     st.wYear = 2014 ;111     st.wMonth = 8 ;112     //st.wDayOfWeek = 113     st.wDay = 10 ;114     st.wHour = 17 ;115     st.wMinute = 12;116     st.wSecond = 0 ;117     st.wMilliseconds = 0 ;118 119     SystemTimeToFileTime(&st,&ftLocal);120 121     LocalFileTimeToFileTime(&ftLocal,&ftUTC) ;122 123     liUTC.LowPart = ftUTC.dwLowDateTime ;124     liUTC.HighPart = ftUTC.dwHighDateTime ;125 126     SetWaitableTimer(g_hTimer,&liUTC,1000,NULL,NULL,FALSE);127 128     //创建线程1129     HANDLE hThreadOne = CreateThread(NULL,0,ThreadFunOne,0,0,NULL);130     CloseHandle(hThreadOne);131 132     //创建线程2133     HANDLE hThreadTwo = CreateThread(NULL,0,ThreadFunTwo,0,0,NULL);134     CloseHandle(hThreadTwo);135 136     //让主线程先挂起,确保其它线程执行完成137 138     getchar();139     cout<<g_x<<endl;140     return 0 ;141 }142 143 DWORD WINAPI ThreadFunOne(PVOID pvParam) 144 {145     while(1)146     {147         WaitForSingleObject(g_hTimer,INFINITE);148         g_x++;149         cout<<"我是ThreadFunOne:"<<g_x<<endl;150     }151     return 0;152 }153 154 DWORD WINAPI ThreadFunTwo(PVOID pvParam)155 {156     while (1)157     {158         WaitForSingleObject(g_hTimer,INFINITE);159         g_x++;    160         cout<<"我是ThreadFunTwo:"<<g_x<<endl;161     }162     return 0;163 }