1. 如果做游戏开发,为了时间单独写一个线程不太划算,CreateWaitableTimerA之类的是内核对象,因为多个时钟都有同一个名称,就可以让多个线程同时读取一个时钟。。
2. 如果要用到多个定时器,应该设定好每个定时器的名字,如果是匿名那就只能是一个。
3.例子
#include<stdio.h> #include <stdlib.h> #include <Windows.h> int main() { HANDLE time1 = CreateWaitableTimerA(NULL, TRUE, "haihua"); if (time1==NULL) { printf("创建失败"); } LARGE_INTEGER mytime; //大整数,其本质是一个结构体 mytime.QuadPart = -50000000; //单位是0.1微秒,设置为5秒之后启动定时器。
if (!SetWaitableTimer(time1,&mytime,0,0,0,0)) { printf("设置失败"); } if (WaitForSingleObject(time1,INFINITE)==WAIT_OBJECT_0) { //如果等于WAIT_OBJECT_0,意味着得到消息。 printf("wait ok"); } else { printf("wait no"); } system("pause"); }
时间定时器还允许回调函数
#include<stdio.h> #include <stdlib.h> #include <Windows.h>
//函数指针作为参数,他调用的函数就是回调函数。
VOID CALLBACK timerun(void *parg,DWORD timearg,DWORD timehigh) { DWORD dwindex = *(DWORD *)parg; printf(" 第%d次", dwindex); //MessageBoxA(0, "1", "2", 0); } int main() { HANDLE time1 = CreateWaitableTimerA(NULL, TRUE, "haihua");//创建时钟 if (time1 == NULL) { printf("创建失败"); } LARGE_INTEGER mytime; //设定定时器从何时开始有信号
//LARGE_INTEGER是union;用于表示一64位有符号整数值 mytime.QuadPart = -50000000; //单位是0.1微妙, DWORD dwparam = 1;//设置定时器 if (SetWaitableTimer(time1, &mytime, 3000, timerun, &dwparam, FALSE)) {
//3000,表示3000毫秒执行一次循环。 printf("等待5秒开始干活"); for (int i = 0; i < 15; i++, dwparam++)//循环多少次 { SleepEx(INFINITE, TRUE);
} } //使用setwaitabletimer启动计时器后,sleepex进入等待,5s后回调函数被触发,然后每3秒打印一次。
CancelWaitableTimer(time1);//取消计时器使用 CloseHandle(time1); system("pause"); }
3.用到的函数:
- CreatWaitbleTimer()
函数原型:
WINBASEAPI __out HANDLE WINAPI CreateWaitableTimer(
__in_opt LPSECURITY_ATTRIBUTES lpTimerAttributes,
__in BOOL bManualReset,
__in_opt LPCWSTR lpTimerName
);
参数:
lpTimerAttributes是设置定时器的属性。
bManualReset是是否手动复位。
lpTimerName是定时器的名称
- SetWaitableTimer()
函数原型: WINBASEAPI BOOL WINAPI SetWaitableTimer( __in HANDLE hTimer, __in const LARGE_INTEGER *lpDueTime, __in LONG lPeriod, __in_opt PTIMERAPCROUTINE pfnCompletionRoutine, __in_opt LPVOID lpArgToCompletionRoutine, __in BOOL fResume ); 参数: hTimer 定时器的句柄。 lpDueTime 设定定时器从何时开始有信号 lPeriod 定时器周期 pfnCompletionRoutine 设置回调函数。 lpArgToCompletionRoutine 传送给回调函数的参数。 fResume 设置系统是否自动恢复。
- SleepEX()
功能:SleepEx函数中止当前线程运行直到指定的条件被触发。当以下任意一点出现时,当前线程将恢复运行。
- I/O回调函数被调用
- Asynchronous Procedure Call(APC)异步函数被插入线程
- 当前线程休眠时间超过最小超时值
函数原型:
DWORD WINAPI SleepEx(DWORD dwMilliseconds,BOOL bAlertable);
参数:
dwMilliseconds将线程挂起(等待)的毫秒时间长度。如设为常数INFINITE,表示将一个线程永久性的催眠
bAlertable 一般设为True,如果是 False, SleepEx 将不会关照 APC 函数是否入列;若是 True, 只要
有 APC 函数申请, SleepEx 不管第一个参数如何都会把 APC 推入队列并随 APC 函数一起返回.