可等待定时器是这样一种内核对象

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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纳秒为单位

相关文档
最新文档