本文的目的是介绍Windows的各种计时器的用途.
Windows大概有4种计时器, 标准Win32计时器, 多媒体计时器, 可等待(waitable)计时器, 队列计时器.
这里讲的计时器是指Windows原生的计时器, 与框架(比如.net)无关.
还有一个基于QueryPerformanceFrequency
and QueryPerformanceCounter这两个函数的计时器, 我们不纳入考虑, 因为, 这两个函数只能实现测定时间间隔的功能, 而不能像Timer一样
定时触发.
时间的精度是有限的, 而且Windows也不是一个实时操作系统, 所以我们不能期待计时器能准确地处理很小的时间间隔(比如10ms).
标准Win32计时器
人们一般提到的计时器就是指这种计时器,这是一个用户态的计时器, 依赖Windows消息机制.
相关函数:
UINT_PTR SetTimer(HWND hWnd, UINT_PTR nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc);
BOOL KillTimer(HWND hWnd, UINT_PTR uIDEvent);
一般, 这个计时器在跟UI线程里面使用的, 单线程操作, 没有安全隐患, 在有WM_TIMER时回调函数lpTimerFunc会被DefWindowProc调用, 也是单线程的.
其实控制台程序也可以使用这个计时器, SetTimer的第一个参数hWnd为NULL时, windows会把WM_TIMER消息发送给进程的消息队列.
你只要在程序里面开启一个线程, 线程里面写个消息循环, 就可以安心地在console程序里面使用这个计时器了.
多媒体计时器
这个计时器不依赖Windows消息机制, 也是用户态的.
使用时你需要出具一个回调函数, OS会在计时器触发的时候, 开启一个线程, 在线程里面执行这个回调函数, 所以需要在回调函数里面考虑线程同步的问题.
我曾在控制台中使用这个计时器, 因为不想为消息循环开一个线程.
相关函数:
MMRESULT timeSetEvent(UINT uDelay, UINT uResolution, LPTIMECALLBACK lpTimeProc, DWORD dwUser, UINT fuEvent); void CALLBACK TimeProc(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2); MMRESULT timeKillEvent(UINT uTimerID);
可等待计时器
该计时器被设计用于需要被阻塞一段时间的线程中.
这个计时器是一个可以在特定时间或者按照一定周期触发的内核对象.
可以设置回调函数(异步过程调用APC), 回调函数被称作complete routine.
一般这样使用 ,设定好定时器, 然后线程等待这个信号量即可.
相关函数:
HANDLE CreateWaitableTimer(LPSECURITY_ATTRIBUTES lpTimerAttributes, BOOL bManualReset, LPCTSTR lpTimerName); BOOL SetWaitableTimer(HANDLE hTimer, const LARGE_INTEGER *pDueTime, LONG lPeriod, PTIMERAPCROUTINE pfnCompletionRoutine, LPVOID lpArgToCompletionRoutine, BOOL fResume); BOOL CancelWaitableTimer(HANDLE hTimer);
这个计时器是个内核对象, 所以可以在多进程之间共享, 这正是这个计时器可以与上面两个计时器有不同用途的原因.
队列计时器
这个东西跟Windows的线程池有关, 用户提供的回调函数会在Windows线程池里面的线程中运行.
相关函数:
BOOL CreateTimerQueueTimer(PHANDLE phNewTimer, HANDLE TimerQueue ,
WAITORTIMERCALLBACK Callback, PVOID Parameter, DWORD DueTime,
DWORD Period, ULONG Flags);
VOID CALLBACK WaitOrTimerCallback(PVOID lpParameter, BOOLEAN TimerOrWaitFired);
BOOL DeleteTimerQueueTimer(HANDLE TimerQueue, HANDLE Timer, HANDLE CompletionEvent);
大部分内容翻译自: http://www.codeproject.com/Articles/1236/Timers-Tutorial
gl&hf~