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 //定义线程函数2 100 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 //创建线程1 129 HANDLE hThreadOne = CreateThread(NULL,0,ThreadFunOne,0,0,NULL); 130 CloseHandle(hThreadOne); 131 132 //创建线程2 133 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 }
线程同步——内核对象实现线程同步——可等待计时器内核对象
时间: 2024-12-18 13:52:28