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

  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 }

 

原文地址:https://www.cnblogs.com/yfyzy/p/3916200.html