多线程 -- 可等待的计时器内核对象
来源:互联网 发布:mac os x 10.11.3 编辑:程序博客网 时间:2024/05/17 01:33
可等待的计时器内核对象
下面的函数CreateWaitableTimer用以创建一个计时器内核对象:
HANDLE
WINAPI CreateWaitableTimer(
__in_opt LPSECURITY_ATTRIBUTES lpTimerAttributes,
__in
BOOL
bManualReset,
__in_opt
LPCTSTR
lpTimerName
);
第一和第三个参数与内核对象的共有特性有关,与线程同步无关,这里不再阐述,通常传入NULL即可。参数bManualReset表示手动重置(TRUE)还是自动重置
(FALSE)。如果是手动重置的话,当内核对象触发时,所有等待的线程都将变为可调度状态;如果是自动重置的话,只有一个线程会被切换到可调度状态。计时器对象被创
建的时候总是非触发状态,只有调用下面的SetWaitableTimer才能启动计时器并在设置的时间触发对象:
BOOL
WINAPI SetWaitableTimer(
__in
HANDLE
hTimer,
__in
const
LARGE_INTEGER *pDueTime,
__in
LONG
lPeriod,
__in_opt PTIMERAPCROUTINE pfnCompletionRoutine,
__in_opt
LPVOID
lpArgToCompletionRoutine,
__in
BOOL
fResume
);
- hTimer:计时器对象句柄
- pDueTime:表示计时器第一次触发的时间。详见下面的例子
- lPeriod:表示计时器第一次触发后,以什么频度触发,详见下面的例子
- pfnCompletionRoutine:当触发时需要执行的异步过程调用(asynchronous procedure call, APC),感觉在线程同步方面使用不多,此处略过,详情可查看MSDN
- lpArgToCompletionRoutine:异步过程调用的传入参数
- fResume是否唤醒休眠的系统
下面这个例子把计时器触发事件设置为2008年1月1日下午1:00,之后每隔6小时触发一次:
HANDLE
hTimer;
SYSTEMTIME st;
FILETIME ftLocal,ftUTC;
LARGE_INTEGER liUTC;
hTimer = CreateWaitableTimer(NULL,FALSE,NULL);
st.wYear = 2008;
st.wMonth = 1;
st.wDayOfWeek = 0;
st.wDay = 1;
st.wHour = 13;
st.wMinute = 0;
st.wSecond = 0;
st,wMilliseconds= 0;
SystemTimeToFileTime(&st,&ftLocal);
LocalFileTimeToFileTime(&ftLocal,&ftUTC);
liUTC.LowPart = ftUTC.dwLowDateTime;
liUTC.HighPart = ftUTC.dwHighDateTime;
SetWaitableTimer(hTimer,&liUTC,6*60*60*1000,NULL,NULL,FALSE);
上面的代码利用SYSTEMTIME结构和FILETIME结构来转换LARGE_INTEGER结构。对于SYSTEMTIME,可用SystemTimeToFileTime转化成FILETIME;而可用
LocalFileTimeToFileTime把FILETIME转成UTC时间,因为SetWaitableTimer的第二个参数始终认为是UTC时间。FILETIME时间更LARGE_INTEGER具有相同的二进制
结构,但是由于FILETIME对齐到32位边界,而LARGE_INTEGER对齐到64位边界,因此,为了避免数据对齐问题,不要直接将FILETIME强制转换成LARGE_INTEGER传
入SetWaitableTimer。顺便提一句,LARGE_INTEGER是以100ns为计时粒度,并且它是个联合体,如果在支持64位整数的编译器中,LARGE_INTEGER只有一个
QuadPart成员。除了为LARGE_INTEGER传入一个绝对时间,也可以为其传入一个相对时间,比如:
LARGE_INTEGER li;
li.QuadPart = -(5 * 10000000);
lPeriod是以毫秒为单位的间隔时间。如果传入0,计时器只会在指定时间触发一次,不会间隔触发。
SetTimer和计时器内核对象
任何有经验的Windows开发人员会立即把计时器内核对象跟用户计时器(通过SetTimer函数来设置)进行比较。两者最大的区别在于用户计时器需要在应用程序中使用大量
的用户界面基础设施,从而消耗更多的资源。另外,计时器内核对象可以在多个线程间共享(通过某种共享内核对象的方式),而且可以具备安全性。
用户计时器通过产生WM_TIMER消息,将其送回调用SetTimer线程(对于回调计时器来说),或者创建窗口(对于基于窗口的计时器来说)。因此,当一个用户计时器触发
的时候只有一个线程能被通知;而内核对象的触发可以通知多个线程。
如果打算计时器触发时做一些与用户界面相关的操作,使用用户计时器会方便一些。
出处:http://www.cnblogs.com/P_Chou/archive/2012/07/07/timer-in-thread-sync.html
- 多线程 -- 可等待的计时器内核对象
- 可等待的计时器内核对象
- 白话windows多线程同步之可等待计时器内核对象
- 可等待计时器内核对象的使用(CreateWaitableTimer)
- windows核心编程-可等待的计时器内核对象
- 内核对象--可等待计时器WaitableTimer(一)
- 内核对象--可等待计时器WaitableTimer(二)
- Chapter09-“内核模式下的线程同步”之可等待的计时器内核对象
- 可等待的计时器
- 20170716Windows11_3_可等待计时器对象
- 线程同步——内核对象(互斥、事件、信号量、可等待计时器)
- 可等待的计时器与APC调用
- 可等待计时器
- 多线程 -- 等待函数、事件内核对象
- 等待定时器内核对象
- 多线程的计时器
- -【内核对象线程同步】成功等待的副作用
- 【内核对象线程同步】成功等待的副作用
- 多线程 -- Slim 读/写锁
- 设计模式 浅析
- Compiling Fortran
- spring 依赖注入的学习
- 华东交通大学2013年ACM“双基”程序设计竞赛
- 多线程 -- 可等待的计时器内核对象
- java enum(枚举)使用详解 + 总结
- Java学习笔记——利用接口和observer实现对象监视
- List集合之间的连接
- Sum Sum Sum
- 通达OA 常用内置函数示例(图文)
- 多线程 -- 原子访问
- UIBinder template should be in client package.
- 黑马程序员 反射