猿问

如何使用C++11实现跨平台的定时器timer

Cats萌萌
浏览 1839回答 2
2回答

梵蒂冈之花

一个Timer的实现需要具备以下几个行为:StartTimer(Interval, ExpiryAction)注册一个时间间隔为 Interval 后执行 ExpiryAction 的定时器实例,其中,返回 TimerId 以区分在定时器系统中的其他定时器实例。StopTimer(TimerId)根据 TimerId 找到注册的定时器实例并执行 Stop 。PerTickBookkeeping()在一个 Tick 时间粒度内,定时器系统需要执行的动作,它最主要的行为,就是检查定时器系统中,是否有定时器实例已经到期。具体的代码实现思路就是:在StartTimer的时候,把 当前时间 + Interval作为key放入一个容器,然后在Loop的每次Tick里,从容器里面选出一个最小的key与当前时间比较,如果key小于当前时间,则这个key代表的timer就是expired,需要执行它的ExpiryAction(一般为回调)。这里有两个实现的细节:获取当前时间包含时间精度,使用系统时间还是CPU时间(asio里的deadline_timer和steady_timer的区别)常用的API是:Windows: QueryPerformanceFrequency() 和 QueryPerformanceCounter()Linux: clock_gettime()OSX: gettimeofday()或者mach_absolute_time()当然在C++11里也可以偷懒使用chrono的high_resolution_clock std::chrono::high_resolution_clock2.timer容器的选择容器应该能够在很短的时间内找到MinValue最小堆的find-min复杂度是O(1),所以蛮受人喜欢的STL里提供有堆的API,make_heap, push_heap, pop_heap, sort_heap3. PerTickBookkeeping是放在主循环线程还是另起线程另起线程需要做好线程间通信,asio和skynet有单独的timer线程
随时随地看视频慕课网APP
我要回答