QQ交流群:198941541
前面讲过,ascs支持定时器(由asio实现),socket和object_pool都继承自timer对象,所以你几乎可以在任意地方使用定时器。下面罗列一下使用定时器需要注意的地方以及定制化定时器等:
如果定义宏ASCS_USE_STEADY_TIMER,将使用asio::steady_timer实现定时器,否则用asio::system_timer;对于st_asio_wrapper库,宏ST_ASIO_USE_STEADY_TIMER表示使用boost::asio::steady_timer,宏ST_ASIO_USE_SYSTEM_TIMER表示使用boost::asio::system_timer,否则使用boost::asio::deadline_timer。
如果定义宏ASCS_ALIGNED_TIMER,ascs会把定时器到达之后的处理时间减去再开启下一次定时器(如果定时器回调函数返回true的话),达到的效果就是(假如处理时间为1秒,定时器间隔为10秒,开启时间在0:0:0):0:0:10, 0:0:20, 0:0:30, ...,对比不定义宏ASCS_ALIGNED_TIMER的效果是:0:0:10, 0:0:11, 0:0:12, ...
定时器通过id(unsigned short)区分,你的id和ascs使用的id本质上并没有区别,只是值不同,所以我们需要避免id重复(如果id重复了,后启动的定时器将覆盖先启动的定时器,不管这个定时器是不是你创建的),方法就是每个类都约定一个自己需要的定时器id范围,比如一个ascs类A,它一定会有一个静态常量A::TIMER_END(你访问它时,可能需要通过typename A::TIMER_END),你继承自A,你的定时器id不能小于A::TIMER_END(可以等于),这样定时器id就不会重复了,如果你的类也要被继承,推荐沿用ascs这套机制(也定义一个TIMER_END,你自己不要使用它,供继承者用它作为定时器id的起始值)。
定时器到期之后,ascs会回调你的回调函数,如果回调函数返回false,将停止定时器,否则马上再次开始定时器,在回调里面,你可以修改定时器的各种属性(change_timer_xxxx)然后返回true以修改定时器,你甚至可以在回调里面再次开启自己(set_timer)然后返回false(如果你不修改定时器,推荐直接返回true,这样最简单)。当进程退出时,你无需显示停止所有定时器,ascs会做这些工作,不管定时器是不是它自己创建的。
定时器的线程安全性(非常重要):不同timer对象里面的定时器,不管id相不相同,回调总是并发的;同一个timer对象里面的不同定时器(id不同),回调也是并发的;同一个timer对象里面的同一个定时器,回调可以认为是不会并发(除非你在回调里面重新开启了自己,然后又工作了足够长的时间才返回false,那么回调可能是并发的)的。再说说多线程安全问题,只有对同一个timer对象(每个socket都继承自timer类,所以不同的socket拥有不同的timer对象)里面的同一个定时器做多线程操作(比如开启/关闭定时器,修改定时器等)时才需要加锁,其它任何情况下都是多线程安全的。
上一篇 ascs 简明开发教程(17) 下一篇 ascs 简明开发教程(19)