可等待定时器是这样一种内核对象
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
可等待定时器是这样一种内核对象,它们会在某个指定的时间触发,或每隔一段时间触发一次。它们通常用来在某个时间执行一些操作。
CreateWaitableTimer函数用于创建一个可等待定时器:
HANDLE WINAPI CreateWaitableTimer(
__in_opt LPSECURITY_ATTRIBUTES lpTimerAttributes, //安全描述符,为NULL时使用默认的
//且该句柄不被子进程继承
__in BOOL bManualReset, //要创建一个手动重置定时器还是一个自动重置计时器
//当手动重置计时器被触发时,正在等待该计时器的所有线程都会变成可调度状态
//当自动重置计时器被触发时,只有一个正在等待该计时的线程会变成可调度状态
__in_opt LPCTSTR lpTimerName //该可等待计时器的名称
);
函数OpenWaitableTimer用于得到一个已经存在的可等待计时器的句柄,该句柄与当前进程相关联:
HANDLE WINAPI OpenWaitableTimer(
__in DWORD dwDesiredAccess, //访问权限
__in BOOL bInheritHandle, //是否允许子进程继承该句柄
__in LPCTSTR lpTimerName //要打开的对象名称
);
在创建的时候,可等待的计时器对象总是处于未触发状态。当我们想要触发计时器时,必须调用SetWaitableTimer函数:
BOOL WINAPI SetWaitableTimer(
__in HANDLE hTimer, //想要触发的计时器
__in const LARGE_INTEGER *pDueTime, //计时器第一次触发的时间
__in LONG lPeriod, //第一次触发后,计时器的触发频度
__in_opt PTIMERAPCROUTINE pfnCompletionRoutine, //异步过程调用APC函数
__in_opt LPVOID lpArgToCompletionRoutine, //APC函数的参数
__in BOOL fResume //是否继续执行,一般传FALSE
);
函数CancelWaitableTimer用来将指定的计时器取消:
BOOL WINAPI CancelWaitableTimer(
__in HANDLE hTimer
);
这样计时器就永远不会触发了,除非以后再调用SetWaitableTimer来对它进行重置。如果想要改变触发器的触发时间,不必先调用CancelWaitableTimer,因为每次调用SetWaitableTimer 都会在设置新的触发时间之前将原来的触发时间取消掉。
下面代码把计时器的第一次触发时间设置为2011年1月1日下午1:00,之后每隔6小时触发一次:
//声明局部变量
HANDLE hTimer;
SYSTEMTIME st;
FILETIME ftLocal, ftUTC;
LARGE_INTEGER liUTC;
//创建自动重置定时器
hTime = CreateWaitableTime(NULL, FALSE, NULL);
//设置第一次触发时间,这是本地时间
st.wYear = 2011;
st.wMonth = 1;
st.wDayOfWeek = 0; //忽略
st.wDay = 1;
st.wHout = 13;
st.wMinute = 0;
st.wSecond = 0;
st.wMilliseconds = 0;
SystemTimeToFileTime(&st, &ftLocal);
//将本地时间转为UTC时间(因为SetWaitableTimer函数传入的时间始终是全球标准时间)LocalFileTimeToFileTime(&ftLocal, &ftUTC);
//虽然FILETIME结构和LARGE_INTEGER结构的二进制格式完全相同
//但它们的结构对齐方式不同(FILETIME对齐到32位边界,LARGE_INTEGER
//对齐到64位边界),因此不能强制转换
liUTC.LowPart = ftUTC.dwLowDateTime;
liUTC.HighPart = ftUTC.dwHighDateTime;
//设置定时器
SetWaitableTimer(hTimer, &liUTC, 6*60*60*1000,
NULL, NULL, FALSE);
...
在上面代码中,我们给定时器第一次触发时间指定的是绝对时间,也可以指定一个相对时间,只要将pDueTime参数中传入一个负值,且传入的值必须是100纳秒的整数倍。换算关系如下:
1秒= 1000毫秒= 1000 000微妙= 10 000 000个100纳秒
下面代码把计时器第一次触发时间设置为SetWaitableTimer函数调用结束后的10秒钟:
#define _WIN32_WINNT 0x0500
#include
#include
int main()
{
HANDLE hTimer = NULL;
LARGE_INTEGER liDueTime;
liDueTime.QuadPart = -100000000LL; //10秒,以100纳秒为单位