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

 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 }

 

你可能感兴趣的:(线程同步)