博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C语言实现定时器
阅读量:2029 次
发布时间:2019-04-28

本文共 7718 字,大约阅读时间需要 25 分钟。

目录


timer.h

#ifndef __TIMER_H#define __TIMER_H 1#include 
#include
#include "list.h"struct timer_node { unsigned long int timerid; struct timeval timeout; struct timeval interval; bool isloop; void *arg; void (*callback)(void *arg); struct list_head list;};void timer_initial();unsigned long int timer_new(bool is_loop, void (*callback)(void *arg), void *arg, long sec, long usec);int timer_del(unsigned long int timerid);#endif //__TIMER_H

timer.c

#define _GNU_SOURCE             /* See feature_test_macros(7) */#include 
#include
#include
#include
#include "log.h"#include "timer.h"#ifndef _unused#define _unused __attribute__((unused))#endifpthread_t timer_routine;LIST_HEAD(timer_list);pthread_mutex_t timer_list_lock = PTHREAD_MUTEX_INITIALIZER;#define CRTL_GT 1#define CRTL_EQ 0#define CRTL_LT (-1)inline int timeval_cmp(struct timeval *in, struct timeval *in2){ if(in->tv_sec > in2->tv_sec) { return CRTL_GT; } else if(in->tv_sec == in2->tv_sec) { if( in->tv_usec > in2->tv_usec ) { return CRTL_GT; } else if (in->tv_usec == in2->tv_usec) { return CRTL_EQ; } else { return CRTL_LT; } } else { return CRTL_LT; } return CRTL_EQ;}inline void timeval_add(struct timeval *in, struct timeval *in2, struct timeval *out){ out->tv_sec = in->tv_sec + in2->tv_sec + (in->tv_usec+in2->tv_usec)/1000000; out->tv_usec = (in->tv_usec+in2->tv_usec)%1000000;}inline int timeval_subabs(struct timeval *in1, struct timeval *in2, struct timeval *out){ time_t in1Sec = in1->tv_sec; time_t in2Sec = in2->tv_sec; long in1uSec = in1->tv_usec; long in2uSec = in2->tv_usec; int cmp = timeval_cmp(in1, in2); if(cmp == CRTL_GT) { out->tv_usec = in1uSec+((in1uSec
tv_sec = in1Sec + ((in1uSec
tv_sec = 0; out->tv_usec = 0; } else if(cmp == CRTL_LT) { out->tv_usec = in2uSec+((in2uSec
tv_sec = in2Sec + ((in2uSec
>> %lx, %lx\n", __list_ite_timer->timer_id, timeid); if( __list_ite_timer->timerid == timeid ) { return __list_ite_timer; } if(list_is_last(&__list_ite_timer->list, &timer_list)) {// __crtl_dbg("Last NOde no OK.\n"); return NULL; } if( __list_ite_next_timer->timerid == timeid ) { return __list_ite_next_timer; } else { __list_ite_timer = __list_ite_next_timer; } } debug("Not exist.\n"); return NULL;}/* 添加定时器到定时器链表 */inline static int timer_add_to_list(struct timer_node *__insert_timer){ struct timer_node *__list_ite_timer = NULL; struct timer_node *_unused __list_ite_next_timer = NULL; struct timer_node *_unused __small_timer = NULL; struct timer_node *_unused __big_timer = NULL; struct timeval time_interval = {0, 0}; /** * 1.Find the location of insert timer * * __small_timer __big_timer * * 2.Insert new timer * __small_timer __insert_timer __big_timer */ /* 如果为空,直接添加 */ if(list_empty(&timer_list)) { list_add_tail(&__insert_timer->list, &timer_list);// crtl_rbtree_insert(__crtl_timers_tree, __insert_timer, sizeof(struct crtl_timer_struct)); /* 如果不为空,查找位置 */ } else { list_for_each_entry_safe(__list_ite_timer,__list_ite_next_timer, &timer_list, list) { int cmp = timeval_subabs(&__list_ite_timer->timeout, &__insert_timer->timeout, &time_interval); if(cmp == CRTL_GT) { struct timer_node * __list_prev_timer = list_prev_entry(__list_ite_timer, list); list_add(&__insert_timer->list, &__list_prev_timer->list); break; } if(list_is_last(&__list_ite_timer->list, &timer_list)) { list_add(&__insert_timer->list, &__list_ite_timer->list); break; /* 如果不是最后一个定时器, 同时使用 __list_ite_next_timer */ } else { /* 轮询的定时器等于即将插入的定时器,插入*/ if(cmp == CRTL_EQ) { list_add(&__insert_timer->list, &__list_ite_timer->list); break; /* 轮询的定时器小于即将插入的定时器,比较下一个节点 */ } else if(cmp == CRTL_LT) { int cmp_next = timeval_subabs(&__list_ite_next_timer->timeout, &__insert_timer->timeout, &time_interval); /* 下一个节点大于或者等于,直接插入 */ if(cmp_next == CRTL_GT || cmp_next == CRTL_EQ) { list_add(&__insert_timer->list, &__list_ite_timer->list); break; /* 下一个节点小于,继续比较 */ } else if(cmp_next == CRTL_LT) { continue; } } } } } return 0;}static void * sched_timer_list(void *arg) { struct timeval currentTime, time_interval; struct timer_node *__this_timer = NULL, _unused *next_timer, *__list_ite_timer, *__list_ite_next_timer; while(1) { usleep(1000); gettimeofday(&currentTime, NULL); pthread_mutex_lock(&timer_list_lock); if(list_empty(&timer_list)) { pthread_mutex_unlock(&timer_list_lock); continue; }#if 0 list_for_each_entry_safe(__this_timer, next_timer, &timer_list, list) { diff_usec = sub_timeval_usec(&__this_timer->timeout, &current); if(diff_usec < 10000 ) { __this_timer->callback(__this_timer->arg); list_del(&__this_timer->list); if(__this_timer->isloop) { } } __this_timer = next_timer; }#else /* 轮询定时器链表 */ list_for_each_entry_safe(__list_ite_timer,__list_ite_next_timer, &timer_list, list) { __this_timer = __list_ite_timer; if(!list_is_last(&__list_ite_timer->list, &timer_list)) { __list_ite_timer = __list_ite_next_timer; } /* 计算当前时间与定时器超时时间差 */ timeval_subabs(&__this_timer->timeout, &currentTime, &time_interval); /* 如果时间差在刷新间隔内,调度定时器 */ if(10000 >= time_interval.tv_sec*1000000+time_interval.tv_usec) { /* 调度 */ __this_timer->callback(__this_timer->arg); /* 从链表中删除这个定时器 */ list_del_init(&__this_timer->list);// crtl_rbtree_delete(__crtl_timers_tree, __this_timer); /* 是否为循环定时器 */ if(__this_timer->isloop) { /* 获取到期时间:轮询表中将被与GetTimeofDay比较 */ timeval_add(&currentTime, &__this_timer->interval, &__this_timer->timeout); timer_add_to_list(__this_timer); } else { free(__this_timer); } }else { /* 如果这个定时器没到时间,后面的定时器全部没有超时 */ break; } }#endif pthread_mutex_unlock(&timer_list_lock); } return NULL;}/* 创建定时器 */unsigned long int timer_new(bool is_loop, void (*callback)(void *arg), void *arg, long sec, long usec){ unsigned long int timerid = 0; struct timer_node *__timer = malloc(sizeof(struct timer_node)); timerid = __timer->timerid = (unsigned long int)__timer; __timer->isloop = is_loop; struct timeval currentTime = {0,0}; /* 计算并保存间隔时间 */ __timer->interval.tv_sec = sec; __timer->interval.tv_usec = usec; /* 获取当前时间 */ gettimeofday(&currentTime, NULL); /* 获取到期时间:轮询表中将被与GetTimeofDay比较 */ timeval_add(&currentTime, &__timer->interval, &__timer->timeout); /* 置NULL */ __timer->list.next = __timer->list.prev = NULL; __timer->callback = callback; __timer->arg = arg; pthread_mutex_lock(&timer_list_lock); /* 添加到定时器链表 */ timer_add_to_list(__timer); pthread_mutex_unlock(&timer_list_lock); return timerid;}/* 删除定时器 */int timer_del(unsigned long int timerid){ struct timer_node *__this_timer = NULL; pthread_mutex_lock(&timer_list_lock); __this_timer = get_timer_byid(timerid); if((!__this_timer)) { warning("null pointer error.\n"); pthread_mutex_unlock(&timer_list_lock); return -1; } /* 从链表中删除这个定时器 */ list_del_init(&__this_timer->list); pthread_mutex_unlock(&timer_list_lock); free(__this_timer); return 0;}//void timer_initial(){ pthread_create(&timer_routine, NULL, sched_timer_list, NULL); pthread_setname_np(timer_routine, "timer");}

测试代码

void test_timer() {    static unsigned long int timerid[10];        void timer_callback(void*arg) {        static volatile int count = 0;        count++;        unsigned long int *timerid = (unsigned long int *)arg;        error("timerid = %ld, count = %d\n", *timerid, count);    }        int i=0;    for(i=0;i<10;i++)        timerid[i] = timer_new(true, timer_callback, &timerid[i], 1, 1);        for(i=0;i<10;i++) {        sleep(1);        timer_del(timerid[9-i]);    }    error("----------------------------------\n");    for(i=0;i<10;i++) {        sleep(1);        timerid[i] = timer_new(true, timer_callback, &timerid[i], 1, 1);    }}

 

转载地址:http://nppaf.baihongyu.com/

你可能感兴趣的文章
数据库技术知识点总结之四——乐观锁与悲观锁
查看>>
数据结构技术知识总结之一——二叉树
查看>>
ZooKeeper 技术知识总结之二——ZK 惊群与脑裂
查看>>
Java并发技术总结之一——Java线程池
查看>>
Java并发技术总结之二——ThreadLocal
查看>>
Java并发技术总结之三——线程状态
查看>>
Java并发技术总结之四——CAS
查看>>
Java并发技术总结之五——AQS
查看>>
JVM技术总结之二——GC机制
查看>>
JVM技术总结之四——JVM内存结构
查看>>
Lucene基本知识入门
查看>>
Windows系统下通过PSCP传输文件至BeagleBone Black
查看>>
OpenCV像素点邻域遍历效率比较,以及访问像素点的几种方法
查看>>
背景提取算法——帧间差分法、背景差分法、ViBe算法、ViBe+算法
查看>>
“王大锤の非诚勿扰” —— Spring IoC / DI 思想详述
查看>>
服务假死问题解决过程实记(三)——缓存问题优化
查看>>
Individual Homework -----questions about the text book by 张静
查看>>
[初心者适用]如何为代码编写基本的文档
查看>>
Daily Scrum 第五天!
查看>>
DailyScrum beta 第三天!
查看>>