您的位置:首页 > 其它

第九章 线程与内核对象的同步(3)

2009-05-30 10:19 232 查看
三、等待定时器内核对象

等待定时器,是在某个时间或按规定的间隔时间发出自己的信号通知的内核对象。通常用来在某个时间执行某个操作。

创建等待定时器内核对象

HANDLE CreateWaitableTimer(PSECURITY_ATTRIBUTES psa, BOOL fManualReset,

PCTSTR pszName); //参数同CreateEvent

当发出人工重置的定时器信号通知时,等待该定时器的所有线程均变为可调度线程。当发出自动重置的定时器信号通知时,只有一个等待的线程变为可调度线程。

HANDLE OpenWaitableTimer(DWORD dwDesiredAccess, BOOL bInheritHandle,

PCTSTR pszName);

进程可以通过调用OpenWaitableTimer获得它自己的与进程相关的现有等待定时器的句柄。

等待定时器内核对象的设定

等待定时器对象总是在未通知状态中创建。必须调用SetWaitableTimer函数来告诉定时器你想在何时让它成为已通知状态。

BOOL SetWaitableTimer(HANDLE hTimer, const LARGE_INTEGER * pDueTime,

LONG lPeriod, PTIMERAPCROUTINE pfnCompletionRoutine,

PVOID pvArgToCompletionRoutine, BOOL fResume);

fResume hTimer指定要设置的定时器。pDueTime设定定时器第一次报时的时间,lPeriod设定定时器报时的时间间隔,以毫秒为单位(pDueTime和lPeriod一起使用),lPeriod传0表示只报时一次。pfnCompletionRoutine指定零或者计时器触发时要调用的一个函数的地址。可在标准模块中用一个函数通过AddressOf操作符提供这个地址。或者使用此类ocx控件。lpArgToCompletionRoutine传递给最终例程的值。fResume设定支持暂停和恢复的计算机。

BOOL CancelWaitableTimer(HANDLE hTimer);

取出定时器的句柄并将它撤消,可以调用SetWaitableTimer重新设置定时器。

让等待定时器给A P C项排队

Windows允许定时器给在定时器得到通知信号时SetWaitableeTimemer函数的线程的异步过程调用(A P C)进行排队。

调用SetWaitableTimer时,同时为pfnCompletionRoutine和pvArgCompletionRoutine参数传递N U L L当规定的时间到来时,就向定时器发出通知信号。但是,如果要到了规定的时间让定时器给一个APC排队,则必须传递定时器A P C例程的地址,且这个例程是你必须实现的。

VOID APIENTRY TimerAPCRoutine (PVOID pvArgToCompletionRoutine,

DWORD dwTimerLowValue, DWORD dwTimerHighValue);

该函数可以在定时器报时的时候由调用SetWaitableTimer函数的同一线程来调用,但是只有在调用线程在等待状态下才能调用。(即该线程须在下列函数调用中等待:SleepEx、 WaitForSingleObjectEx、WaitForMultipleObjectsEx、MsgWaitForMultipleObjectesEx、SingleObjectAndWait)。若线程不在其中等待,系统不会为定时器APC例程排队(防止线程的APC队列里塞满定时器APC通知,浪费内存)。定时器报时的时候,如果线程处于等待中,就会调用APC例程。

线程不应该等待定时器的句柄,也不应该以待命的方式等待定时器。

4、定时器的松散特性

定时器常常用于通信协议中。 当不得已创建了很多定时器对象时,可以考虑使CreateTimerQueueTimer函数以减少应用程序的开销。应该避免使用定时器APC排队(而使用I / O完成端口机制)。

用户定时器, SetTimer函数进行设置, 需要在应用程序中设置许多附加的用户界面结构,这使定时器变得资源更加密集。

等待定时器, 属于内核对象,它们可以供多个线程共享,并且是安全的。

用户定时器能够生成WM_TIMER消息,返回给调用 SetTimer(用于回调定时器)的线程和创建窗口(用于基于窗口的定时器)的线程。因此,当用户定时器报时的时候,只有一个线程得到通知。多个线程可以在等待定时器上进行等待,如果定时器是个人工重置的定时器,则可以调度若干个线程。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: