WaitableTimer的实例讲解
2017-08-10 20:11
162 查看
1 基本函数
HANDLE CreateWaitableTimer(
LPSECURITY_ATTRIBUTES lpTimerAttributes,
BOOL bManualReset,
LPCSTR lpTimerName);
lpTimerAttributes,
SECURITY_ATTRIBUTES,指定一个结构,用于设置对象的安全特性,就可使用对象的默认安全设置。
bManualReset
BOOL,如果为TRUE,表示创建一个人工重置计时器;如果为FALSE,则创建一个自动重置计时器。
lpTimerName
LPCSTR,指定可等待计时器对象的名称。如果已经存在拥有这个名字的一个可等待计时器,就直接打开现成的可等待计时器。这个名字不能与一个现有的互斥体、事件、信号机或文件映射的名称相同。
人工重置与自动重置的区别
使用人工重置,则计时结束后所有的等待线程均变为可调度线程;使用自动重置,则只有一个线程变为可调度线程。
BOOL SetWaitableTimer(
HANDLE hTimer,
const LARGE_INTEGER *lpDueTime,
LONG lPeriod,
PTIMERAPCROUTINE pfnCompletionRoutine,
LPVOID lpArgToCompletionRoutine,
BOOL fResume );
hTimer 定时器的句柄。
lpDueTime 设置定时器时间间隔,当设置为正值是绝对时间;当设置为负数是相对时间。
lPeriod 周期。
pfnCompletionRoutine 设置回调函数。
lpArgToCompletionRoutine传送给回调函数的参数。
fResume 设置系统是否自动恢复。
2 控制台程序样例
(巧妙使用了事件对象,实现控制台程序的回调功能)
HANDLE g_hHelpEvent;
void CALLBACK TimerCallback( LPVOID lpArgToCompletionRoutine, DWORD dwTimerLowValue, DWORD dwTimerHighValue )
{//这里处理定时器触发
SetEvent(g_hHelpEvent);
SYSTEMTIME st;
GetLocalTime(&st);
printf("%02d:%02d\n",st.wMinute,st.wSecond);
}
int _tmain(int argc, _TCHAR* argv[])
{
//创建事件内核对象,默认未触发状态
HANDLE hTimer = CreateWaitableTimer(NULL, TRUE, NULL);
//创建事件,设置为未触发状态
g_hHelpEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
SYSTEMTIME st;
GetLocalTime(&st);
//st.wSecond += 40;
FILETIME ft;
SystemTimeToFileTime(&st, &ft);
//转换成UTC时间
FILETIME ftUtc;
LocalFileTimeToFileTime(&ft, &ftUtc);
LARGE_INTEGER fTime={0};//-2*10000000
//fTime.LowPart = ftUtc.dwLowDateTime;
//fTime.HighPart = ftUtc.dwHighDateTime;
//当前时间的后一分钟触发,以后每10秒钟触发一次
BOOL bRet = SetWaitableTimer(hTimer, &fTime, 2*1000, TimerCallback, (LPVOID)hTimer, FALSE);
DWORD dwError = GetLastError();
//将TimerCallback回调加入到系统APC队列后,只能通过SleepEx、WaitForSingleObjectEx、WaitForMultipObjectEx、
//或者SignalObjectAndWait 进入等待状态APC回调函数才能被同一线程调用。
DWORD dwRet=WaitForSingleObject(g_hHelpEvent, 1000);
while( WAIT_TIMEOUT == dwRet)
SleepEx(1000*60, TRUE);
switch( dwRet )
{
case WAIT_OBJECT_0://
printf("定时器对象已经触发\n");
break;
case WAIT_TIMEOUT:
printf("等待超时,自动终止定时器对象\n");
CancelWaitableTimer(hTimer);
break;
case WAIT_FAILED:
printf("WaitForSingleObject调用失败,系统错误码\n");
break;
}
CloseHandle(hTimer);
CloseHandle(g_hHelpEvent);
getchar();
return 0;
}
HANDLE CreateWaitableTimer(
LPSECURITY_ATTRIBUTES lpTimerAttributes,
BOOL bManualReset,
LPCSTR lpTimerName);
lpTimerAttributes,
SECURITY_ATTRIBUTES,指定一个结构,用于设置对象的安全特性,就可使用对象的默认安全设置。
bManualReset
BOOL,如果为TRUE,表示创建一个人工重置计时器;如果为FALSE,则创建一个自动重置计时器。
lpTimerName
LPCSTR,指定可等待计时器对象的名称。如果已经存在拥有这个名字的一个可等待计时器,就直接打开现成的可等待计时器。这个名字不能与一个现有的互斥体、事件、信号机或文件映射的名称相同。
人工重置与自动重置的区别
使用人工重置,则计时结束后所有的等待线程均变为可调度线程;使用自动重置,则只有一个线程变为可调度线程。
BOOL SetWaitableTimer(
HANDLE hTimer,
const LARGE_INTEGER *lpDueTime,
LONG lPeriod,
PTIMERAPCROUTINE pfnCompletionRoutine,
LPVOID lpArgToCompletionRoutine,
BOOL fResume );
hTimer 定时器的句柄。
lpDueTime 设置定时器时间间隔,当设置为正值是绝对时间;当设置为负数是相对时间。
lPeriod 周期。
pfnCompletionRoutine 设置回调函数。
lpArgToCompletionRoutine传送给回调函数的参数。
fResume 设置系统是否自动恢复。
2 控制台程序样例
(巧妙使用了事件对象,实现控制台程序的回调功能)
HANDLE g_hHelpEvent;
void CALLBACK TimerCallback( LPVOID lpArgToCompletionRoutine, DWORD dwTimerLowValue, DWORD dwTimerHighValue )
{//这里处理定时器触发
SetEvent(g_hHelpEvent);
SYSTEMTIME st;
GetLocalTime(&st);
printf("%02d:%02d\n",st.wMinute,st.wSecond);
}
int _tmain(int argc, _TCHAR* argv[])
{
//创建事件内核对象,默认未触发状态
HANDLE hTimer = CreateWaitableTimer(NULL, TRUE, NULL);
//创建事件,设置为未触发状态
g_hHelpEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
SYSTEMTIME st;
GetLocalTime(&st);
//st.wSecond += 40;
FILETIME ft;
SystemTimeToFileTime(&st, &ft);
//转换成UTC时间
FILETIME ftUtc;
LocalFileTimeToFileTime(&ft, &ftUtc);
LARGE_INTEGER fTime={0};//-2*10000000
//fTime.LowPart = ftUtc.dwLowDateTime;
//fTime.HighPart = ftUtc.dwHighDateTime;
//当前时间的后一分钟触发,以后每10秒钟触发一次
BOOL bRet = SetWaitableTimer(hTimer, &fTime, 2*1000, TimerCallback, (LPVOID)hTimer, FALSE);
DWORD dwError = GetLastError();
//将TimerCallback回调加入到系统APC队列后,只能通过SleepEx、WaitForSingleObjectEx、WaitForMultipObjectEx、
//或者SignalObjectAndWait 进入等待状态APC回调函数才能被同一线程调用。
DWORD dwRet=WaitForSingleObject(g_hHelpEvent, 1000);
while( WAIT_TIMEOUT == dwRet)
SleepEx(1000*60, TRUE);
switch( dwRet )
{
case WAIT_OBJECT_0://
printf("定时器对象已经触发\n");
break;
case WAIT_TIMEOUT:
printf("等待超时,自动终止定时器对象\n");
CancelWaitableTimer(hTimer);
break;
case WAIT_FAILED:
printf("WaitForSingleObject调用失败,系统错误码\n");
break;
}
CloseHandle(hTimer);
CloseHandle(g_hHelpEvent);
getchar();
return 0;
}
相关文章推荐
- C# Timer用法及实例讲解
- vue 实现 tomato timer(蕃茄钟)实例讲解
- 实例讲解电源高频变压器的设计方法
- Mybatis 入门之resultMap与resultType讲解实例
- SQL触发器实例讲解
- SpringMVC入门实例及详细讲解
- linux驱动模型开发——linux platform总线机制讲解与实例开发
- Node.js基础入门实例讲解
- Python图像处理之识别图像中的文字(实例讲解)
- EJB3.0 Ant Build.xml实例讲解
- PHP获取远程URL的实例讲解
- 实例讲解表单验证插件Validation的应用
- poi3.9导入导出 讲解实例
- MMC/SD卡驱动实例开发讲解(一)
- Android 依赖注入: Dagger 2 实例讲解(一)
- 实例讲解Android中ContentProvider组件的使用方法
- 通过异步程序调用(APC)实现的定时功能 CreateWaitableTimer和SetWaitableTimer函数
- 实例讲解Java中的接口的作用
- 基于StreamRead和StreamWriter的使用(实例讲解)
- Android学习指南之二十八:Android多媒体(Media)实例讲解