1. CreateTimerQueueTimer
// 创建并启动定时器
BOOL WINAPI CreateTimerQueueTimer(
__out PHANDLE phNewTimer,
__in HANDLE TimerQueue,
__in WAITORTIMERCALLBACK Callback,
__in PVOID Parameter,
__in DWORD DueTime,
__in DWORD Period,
__in ULONG Flags
);
// 删除定时器
BOOL WINAPI DeleteTimerQueueTimer(
__in HANDLE TimerQueue,
__in HANDLE Timer,
__in HANDLE CompletionEvent
);
- 示例
点击(此处)折叠或打开
- // 创建定时器
- if (!CreateTimerQueueTimer(
- &timerId, // timer handle
- NULL, // the default timer queue
- (WAITORTIMERCALLBACK)handler, // 回调函数
- "test", // 传递给回调函数的数据
- 0, // timer启动延迟时间(毫秒)
- 1000, // 周期(毫秒)
- 0)) // flags
- {
- printf("CreateTimerQueueTimer error.(%d)", GetLastError());
- }
- // 回调函数
- static void CALLBACK handler(PVOID lpParam, BOOLEAN TimerOrWaitFired)
- {
- const char* str = (const char*)lpParam;
- printf("str=%s\n", str);
- }
- // 删除定时器
- DeleteTimerQueueTimer(
- NULL, // NULL, the default timer queue
- timerId, // timer handle
- INVALID_HANDLE_VALUE); // 如果此参数设为NULL,有可能导致程序崩溃
2. timeSetEvent
// 创建并启动定时器
MMRESULT timeSetEvent(
UINT uDelay,
UINT uResolution,
LPTIMECALLBACK lpTimeProc,
DWORD_PTR dwUser,
UINT fuEvent);
// 删除定时器
MMRESULT timeKillEvent(UINT uTimerID);
- 示例
点击(此处)折叠或打开
- // 创建定时器
- timerId = timeSetEvent(1000, // 周期(毫秒)
- 100, // 精度(毫秒)
- &handler, // 回调函数
- (DWORD_PTR)"test", // 传递给回调函数的数据
- // 定时器种别(一次性或周期性)
- TIME_PERIODIC | TIME_KILL_SYNCHRONOUS | TIME_CALLBACK_FUNCTION);
- if (timerId == NULL)
- {
- printf("timeSetEvent error.(%d)", GetLastError());
- return;
- }
- // 回调函数
- static void CALLBACK handler(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)
- {
- const char* str = (const char*)dwUser;
- printf("str=%s\n", str);
- }
- // 删除定时器
- timeKillEvent(timerId);
使用此种定时器函数需要依赖库文件Winmm.lib。
3. CreateWaitableTimer
// 创建定时器
HANDLE WINAPI CreateWaitableTimer(
__in LPSECURITY_ATTRIBUTES lpTimerAttributes,
__in BOOL bManualReset,
__in LPCTSTR lpTimerName
);
// 启动定时器
BOOL WINAPI SetWaitableTimer(
__in HANDLE hTimer,
__in const LARGE_INTEGER* pDueTime,
__in LONG lPeriod,
__in PTIMERAPCROUTINE pfnCompletionRoutine,
__in LPVOID lpArgToCompletionRoutine,
__in BOOL fResume
);
// 取消定时器,调用SetWaitableTimer可重新激活定时器
BOOL WINAPI CancelWaitableTimer(
__in HANDLE hTimer
);
- 示例
点击(此处)折叠或打开
- // 创建定时器
- hTimer = CreateWaitableTimer(
- NULL, // Default security attributes
- FALSE, // Create auto-reset timer
- NULL); // Name of waitable timer
- if (hTimer == NULL)
- {
- printf("CreateWaitableTimer error.(%d)", GetLastError());
- return;
- }
- liDueTime.LowPart = 0;
- liDueTime.HighPart = 0;
- // 启动定时器
- bSuccess = SetWaitableTimer(
- hTimer, // Handle to the timer object
- &liDueTime, // When timer will become signaled
- 1000, // Periodic timer interval
- handler, // Completion routine
- "test", // Argument to the completion routine
- FALSE); // Do not restore a suspended system
- if (!bSuccess)
- {
- printf("SetWaitableTimer error.(%d)", GetLastError());
- return;
- }
- // 回调函数
- static void CALLBACK handler(
- LPVOID lpArg, // Data value
- DWORD dwTimerLowValue, // Timer low value
- DWORD dwTimerHighValue ) // Timer high value */
- {
- const char* str = (const char*)lpArg;
- printf("str=%s\n", str);
- }
- // 删除定时器
- CancelWaitableTimer(timerId); // 取消激活
- CloseHandle(timerId); // 关闭句柄
在使用此种定时器时,导致阻塞中的函数select返回值不正常,debug版本下返回-1,这个与linux下
中断发生相似,比较好处理,只要重新调用select函数就好了。但是不能理解的是在release版本下,
它返回正常且select的返回值大于1,也就是多个可读写的描述字准备好了,实际并没有,导致
在下面的处理中调用accept函数时出现异常,不知道为什么,只好放弃使用此种定时器。