[common-sln]: base增加多定时器组件

来源:互联网 发布:jstor数据库怎么用 编辑:程序博客网 时间:2024/06/11 23:27

操作系统现有的APIlinux的定时器:1. 基于信号的setitimer系列----- 信号是进程域,对于同一种信号,只能有一个处理函数;如果别的模块也扑捉同一种信号,那么后面设置的信号处理会覆盖前面的处理方法。2. 基于文件描述符的timer_create系列----- 稍显复杂;而且会"消耗"文件描述符,这不适合于文件描述符需求大且系统文件描述符不足的情景。windows的定时器:1. 基于消息机制的SetTimer系列----- 此消息的响应优先级很低,意味着精度可能不行;感觉底层库用这个来实现也不适合。2. timeSetEvent系列----- 没用过,听说不用多线程;但是只在xp上才有这个。
所以,还是考虑用多线程来轮询:采用的是nanosleep+gettimeofday / Sleep+GetLocalTime来控制精度,理想精度为1ms因为针对每个定时器(定时任务)都涉及到增加、删除、开启、停止操作,所以,感觉用最小堆来做不合适(删除、开启、停止指定任务不方便),至于时间轮方式,则是没想通怎么来定义这个结构与轮询过程,所以目前采用的数据结构是有序链表
文中所谓精度,都是在任务"不"耗时的前提下才可能好的了的
class TimerManager : public BaseUncopy{public:    TimerManager();    ~TimerManager();public:    bool init();    void exit();public:    template <typename T, typename F, typename P>    size_t create_timer_mem(T & t, F f, const P & p);    template <typename T, typename F>    size_t create_timer_mem(T & t, F f);    template <typename F, typename P>    size_t create_timer_ptr(F f, P p);    template <typename F>    size_t create_timer_ptr(F f);    void destroy_timer(size_t id);    bool start_timer(size_t id, bool once, size_t period);    bool stop_timer(size_t id);};

测试代码:

class Test{public:    void test() const    {        std::cout << "void Test::test(void) const" << std::endl;    }    void test(int) volatile    {        std::cout << "void Test::test(int)" << std::endl;    }};void test(void){    std::cout << "void test(void)" << std::endl;}void test(int){    std::cout << "void test(int)" << std::endl;}struct TEST{    void operator () (void) const    {        std::cout << "void TEST::operator () (void) const" << std::endl;    }    void operator () (int)    {        std::cout << "void TEST::operator () (int)" << std::endl;    }};void test_base_timer_manager(void){    TimerManager timer_manager;    if (!timer_manager.init())    {        printf("timer manager init failed\n");        return;    }    void (*ptr1) (void) = test;    void (*ptr2) (int)  = test;    void (Test::*mem1) (void) const   = &Test::test;    void (Test::*mem2) (int) volatile = &Test::test;    Test t;    TEST f;    size_t id1 = timer_manager.create_timer_ptr(ptr1);    size_t id2 = timer_manager.create_timer_ptr(ptr2, 0);    size_t id3 = timer_manager.create_timer_mem(t, mem1);    size_t id4 = timer_manager.create_timer_mem(t, mem2, 0);    size_t id5 = timer_manager.create_timer_ptr(f);    size_t id6 = timer_manager.create_timer_ptr(f, 0);    timer_manager.start_timer(id1, false,  200);    timer_manager.start_timer(id2, false,  300);    timer_manager.start_timer(id3, false,  400);    timer_manager.start_timer(id4, false,  600);    timer_manager.start_timer(id5, false, 1200);    timer_manager.start_timer(id6, false, 2400);    printf("sleep 5000ms begin...\n");    base_millisecond_sleep(5000);    printf("sleep 5000ms end...\n");    timer_manager.stop_timer(id1);    timer_manager.stop_timer(id2);    timer_manager.stop_timer(id3);    timer_manager.stop_timer(id4);    timer_manager.stop_timer(id5);    timer_manager.stop_timer(id6);    printf("sleep 1000ms begin...\n");    base_millisecond_sleep(1000);    printf("sleep 1000ms end...\n");    timer_manager.exit();}
其中:
    printf("sleep 1000ms begin...\n");    base_millisecond_sleep(1000);    printf("sleep 1000ms end...\n");
目的是查看stop_timer之后是否还有任务在执行(看打印而不是stop_timer返回值,只是因为这样更方便看到效果)


参考资料:

http://www.ibm.com/developerworks/cn/linux/l-cn-timers/index.html

http://blog.csdn.net/zhangxinrun/article/details/5914191

原创粉丝点击