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

操作系统现有的API

linux的定时器:
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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值