tbox内部提供了两种定时器实现:timer和ltimerlinux
这里主要讲解下,如何使用timer实现高精度的定时器任务,精确到ms级别,对于低精度的ltimer,能够参考:低精度定时器的使用git
下面先给个简单的例子来讲明:github
/* 定义一个定时器任务处理函数 * * @param killed 表示当前任务是否被tb_timer_task_kill强行kill掉的 * @param priv 投递任务时传入的用户自定义数据指针 */ static tb_void_t tb_demo_timer_task_func(tb_bool_t killed, tb_cpointer_t priv) { } /* 投递一个定时器任务到全局timer中,间隔1000ms,会重复执行 * * 其中tb_true表示是否会重复执行,若是设为tb_false,那么只会执行一次 * tb_null参数,就是传入给任务函数的用户自定义数据指针 */ tb_timer_task_post(tb_timer(), 1000, tb_true, tb_demo_timer_task_func, tb_null);
上面的投递,会在post调用完,马上开始任务的计时和运行,若是想要在10s后,才开始启动定时器,能够这么投递:算法
// 在10s后才开始投递一个定时器任务到全局timer中,间隔1000ms,会重复执行 tb_timer_task_post_after(tb_timer(), 10000, 1000, tb_true, tb_demo_timer_task_func, tb_null);
若是要肯定绝对投递时间,能够这么投递:缓存
// 在指定时间戳tb_time() + 150000才开始投递一个定时器任务到全局timer中,间隔1000ms,会重复执行 // 这里至关于15s后才开始投递 tb_timer_task_post_at(tb_timer(), tb_time() + 150000, 1000, tb_true, tb_demo_timer_task_func, tb_null);
前面使用的post投递接口,都是没法维护和控制任务的,若是想要在某个特定的时刻取消还在执行队列中的定时器任务安全
能够使用下面的方式来维护:服务器
// 建立一个间隔10s的定时器任务,不会重复执行 tb_timer_task_ref_t task = tb_timer_task_init(tb_timer(), 10000, tb_false, tb_demo_timer_task_func, tb_null); // 过段时间后 // ... // 若是以为不想执行这个任务了,能够手动取消掉,这个是线程安全的 if (task) tb_timer_task_kill(tb_timer(), task); // 最后在程序退出时,销毁这个任务资源 if (task) tb_timer_task_exit(tb_timer(), task);
前面的例子都是在全局的默认tb_timer()
中投递的定时器任务,tbox会在后台建立一个单独的线程去维护它的全部任务,若是以为这个太占资源, 本身有特定线程在不断loop的话能够建立个独立的timer,挂接到本身的loop线程中,重用线程资源:并发
// 假设这个是你本身的线程 static tb_pointer_t tb_demo_timer_loop(tb_cpointer_t priv) { // the timer tb_timer_ref_t timer = (tb_ltimer_ref_t)priv; #if 1 // 本身的线程loop while (1) { // 等待特定的定时器延时 // 不必定非得用sleep, 若是你的线程正在处理select/epoll等,能够直接利用这些接口的timeout参数来等待 tb_sleep(tb_timer_delay(timer)); // 本身的一些其余逻辑代码 // ... // 固定调用,脉动一下定时器,很快的,不会长时间阻塞,除非有耗时的任务 tb_timer_spak(timer); } #else // 若是没有其余逻辑代码,那么能够直接用timer自带的loop来代替 tb_timer_loop(timer); #endif // exit it tb_thread_return(tb_null); return tb_null; } /* 建立一个定时器 * * 第一个参数:指定定时器最大并发任务规模,默承认以传0,也能够本身指定规模数 * 第二个参数:是否启用时间戳缓存优化,传tb_false就好了,这个通常用于服务器端高并发处理时的优化 */ tb_timer_ref_t timer = tb_timer_init(0, tb_false); if (timer) { // 投递一些任务 // ... // 退出定时器 tb_timer_exit(timer); }