huyutian

他强由他强,清风拂山岗;他横由他横,明月照大江。他自狠来他自恶,我自一口真气足

  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  20 随笔 :: 47 文章 :: 22 评论 :: 0 Trackbacks
Windows系统三种定时器的分析
目前,Windows下的定时器编程主要有三种方式。
1)SetTimer定时器是利用Windows窗口消息WM_TIMER来实现的。使用方法非常简单,SetTimer创建定时器,KillTimer销毁定时器。使用条件是调用线程必须要有窗口消息队列message queue,因此如果是工作线程就无法使用这种方法。
2)WaitableTimer定时器,其实应该算是一种线程同步对象,CreateWaitableTimer创建定时器对象,SetWaitableTimer设置定时器回调函数,CLoseHandle销毁定时器。WaitableTimer可以跨线程、进程使用,只要知道定时器对象名字(创建定时器时设置)就可以控制该定时器对象了。WaitableTimer定时器的回调函数实际上是一个APC(Asynchronous Procedure Calls)异步过程调用函数。
关于APC方面的知识可参考“谈谈对APC的一点理解”一文http://blog.csdn.net/wwwwly/archive/2009/07/10/4337907.aspx
3)TimerQueueTimer定时器,应该算迄今为止Windows系统最强大的定时器了。他可以支持多种工作模式,而且定时精度也是最高的。
使用时,首先要调用CreateTimerQueue创建一个定时器队列,然后用
CreateTimerQueueTimer来创建一个TimerQueueTimer定时器,
WT_EXECUTEDEFAULT,默认设置,回调函数将进入一个非I/O工作线程队列
WT_EXECUTEINTIMERTHREAD,回调函数作为APC,在定时器线程中被调用,被调用的条件是线程进入可警告等待状态alertable wait status。仅适用于短时任务,否则可能会影响队列中的其他定时器。
WT_EXECUTEINIOTHREAD,回调函数进入一个I/O工作线程队列,
请注意,大多数定时器都需要调用线程进入可警告等待状态alertable wait status,并不是随随便便就能发生定时调用的。一个线程是否进入可警告等待状态可参见微软的说明http://msdn.microsoft.com/en-us/library/ms686307.aspx
A thread goes into an alertable wait state by calling either SleepEx, MsgWaitForMultipleObjectsEx, WaitForSingleObjectEx, or WaitForMultipleObjectsEx, with the function's bAlertable parameter set to TRUE.
所以希望定时器不受这种可警告等待状态的影响,最好是用TimerQueue来完成。
posted on 2011-06-29 10:46 胡雨田 阅读(12636) 评论(2)  编辑 收藏 引用 所属分类: 编程技巧

评论

# re: Windows系统三种定时器的分析 2016-07-15 18:32 Apophis
不是三种,还有另两种高精度定时器,其中一种是 timerSetEvent,不过一个进程中它只支持创建16个,还有一个是 mci 的定时器  回复  更多评论
  

# re: Windows系统三种定时器的分析 2016-07-15 18:37 Apophis
另外,TimerQueueTimer 使用中最需注意的密集的短时调用,一定仔细区分每个定时器需求,来准确使用WT_*控制其创建线程的情况,如果使用默认标记或APC形式时,理论上只要能成果创建线程它一定创建线程,最终可能创建出几百个线程,反而拖慢程序运行(因为它其后还有消除线程的动作,如果当时线程数奇多,它在执行这个过程时会让表层程序莫名其妙的卡顿)  回复  更多评论
  


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理