zoukankan      html  css  js  c++  java
  • 升序定时器的时间链表的全然实现

                                       李邦柱

                                                           helpylee@126.com


    1. 定时器简单介绍

    定时器通常包括至少两个成员:一个超时时间(通常採用相对时间或者超时时间)和一个超时时间到达后的一个回调函数。

    有时候还可能包括回调函数被运行时须要传入的參数,以及是否又一次启动定时器,更改定时器的超时时间等。假设使用链表作为容器来串联全部的定时器。则每一个定时器还要包括指向下一个定时器的指针成员。进一步,假设链表是双向的,则每一个定时器还须要包括指向前一个定时器的指针成员。

     

    2. 升序定时器链表的实现

    #ifndef LST_TIMER
    #define LST_TIMER
    #include<time.h>
    #define BUFFER_SIZE 64
    class Timer;/*向前声明*/*/
    
    /*用户数据结构,包括ip,端口。文件描写叙述符,读缓存,以及定时器*/
    struct client_data
    {
      char ip[BUFFER_SIZE];
      int port;
      int sockfd;
      char buf[BUFFER_SIZE];
      Timer *timer;
    
    };
    
    /*定时器类*/
    class Timer
    {
     public:
    	Timer():prev(NULL),next(NULL){}
     public:
        time_t expire;/*任务的超时时间,此处使用绝对时间*/
    	client_data* user_data;
    	void (*cb_func)(client_data*);/*任务回调函数*/
    	Timer* prev;/*指向前一个定时器*/
    	Timer* next;/*指向后一个定时器*/
    	void* arg;  /*可根据须要进行扩展使用*/
    
    
    };
    
    /*定时器链表,它是一个升序,双向链表。且带有头节点和尾节点*/
    class sort_timer_lst
    {
    public:
    	sort_timer_lst():head(NULL),tail(NULL){}
    	~sort_timer_lst()/*链表被销毁的时候。删除全部的定时器*/
    	{
    		Timer* tmp =head;
    		while(tmp)
    		{
    			head=tmp->next;
    			delete tmp;
    			tmp =head;
    		
    		}
    	}
    	void add_timer(Timer* timer);/*将目标定时器加入到链表中*/
    	bool find_timer(Timer* timer);/*查找目标定时器*/
    	void del_timer(Timer* timer);/*删除目标定时器*/
    	void adjust_timer(Timer* timer);/*当某个定时任务发生变化时。调整相应的定时器在链表的位置,此函数之考的向后调整*/
    	void tick();
    private:	
        void add_timer(Timer* timer,Timer* head);
    	private:	
    	Timer* head;
    	Timer* tail;
    	
    };
    
    
    #endif
    
    lst_timer.cpp

    #include"lst_timer.h"
    
    
    
    void sort_timer_lst::add_timer(Timer* timer)
    {
    	if(!timer) return;
    		if(!head)
    		{
    			head= tail =timer;
    			return ;
    		}
    		
    		if(timer->expire < head->expire)
    		{
    		  timer->next = head;
    		  head ->prev = timer;
    		  head = timer;
    		  return ;
    		
    		}
    		
    		add_timer(timer,head);
    
    
    
    }
    
    
    bool sort_timer_lst:: find_timer(Timer* timer)
    {
    
    	Timer* tmp = head;
    	while(tmp)
    	{
    		if(strcmp(tmp->user_data->stb_id , timer->user_data->stb_id)==0)
    		{
    				
    				return true;
    			
    		}
    			
    		       tmp = tmp->next;
    		
    	}
    		if(!tmp)
    		return false;
    
    }
    
    
    void sort_timer_lst::adjust_timer(Timer*timer)
    {
    	if(!timer)
    		return;
    	
    	Timer*tmp = timer->next;
    	if(!tmp||timer->expire<tmp->expire)
    		return;
    	
    	if(timer==head)
    	{
    		head = head->next;
    		head->prev =NULL;
    		timer->next = NULL;
    		add_timer(timer,head);
    	
    	
    	}
    	else
    	{
    		timer ->prev->next = timer ->next;
    		timer ->next->prev = timer->prev;
    		add_timer(timer,timer->next);
    	
    	}
    	
    
    
    
    }
    
    
    
    void sort_timer_lst::del_timer(Timer* timer)
    {
    
    	if(!timer)
    		return;
    	/*以下条件成立。表示仅仅有一个定时器,即目标定时器*/	
    	if((timer ==head)&&(timer ==tail))
    	{
    		delete timer;
    		head = NULL;
    		tail = NULL;
    		return ;
    			
    		
    	}
    	/*假设链表至少有两个定时器,且目标定时器恰好是头结点*/
    	if(timer == head)
    	{
    		head =head->next;
    		head->prev=NULL;
    		delete timer;
    		return;
    		
    		
    	}
    	/*假设链表至少有两个定时器,目标定时器恰好是尾节点*/
    	if(timer ==tail)
    	{
    		tail = tail ->prev;
    		tail ->next =NULL;
    		delete timer;
    		return;
    		
    	}
    	/*目标定时器假设位于链表头尾之间。则把它前后的定时器串联起来,然后删除目标定时器*/	
    	timer->prev ->next =timer ->next;	
    	timer->next->prev = timer ->prev ;
    	delete timer;
    
    
    
    }
    
    /*主要通过此函数不断检測时候有定时器超时*/
    void sort_timer_lst::tick()
    {
    
    
    	if(!head ) return;
    		
    	time_t cur = time(NULL);
    		
    	Timer* tmp = head;
    		
    	while(tmp)
    	{
    		if(cur<tmp->expire)
    		break;
    			
    		tmp->cb_func(tmp->user_data);/*运行定时器回调函数*/
    			
    		head=tmp->next;
    		if(head)
    		head->prev = NULL;
    			
    		delete tmp;
    		tmp = head;
    		
    	}
    
    
    }
    
    void sort_timer_lst:: add_timer(Timer* timer,Timer* head)
    {
    
    	Timer* prev = head;
    	Timer* tmp = prev->next;
    		
    	while(tmp)
    	{
    		if(timer->expire<tmp->expire)
    		{
    			prev->next =timer ;
    			timer->next = tmp;
    			tmp ->prev = timer;
    			timer ->prev = prev;
    			break;
    			
    			
    		}
    			
    		prev = tmp;
    		tmp =tmp->next;
    		
    		
    	}
    		
    	if(!tmp)
    	{
    		prev->next = timer;
    		timer->prev = prev;
    		timer->next =NULL;
    		tail = timer;
    					
    	}
    
    
    }


    3. 性能分析

    Sort_timer_lst是一个升序链表,其核心函数是tick,相当于一个脉搏。让它每隔一段时间就运行一次。以检測并处理到期的任务。判定定时任务到期的根据是定时的expire值小于或者等于当前时间。

    从运行效率上看加入定时器的任务的时间复杂度为O(n),删除定时器的时间复杂度为O(1),运行任务的时间复杂度是O(1).

    4. 其它高性能定时器

    基于排序链表的定时器存在一个效率的问题。加入定时器的效率偏低,因此能够使用时间轮或者时间堆来解决问题。有兴趣的朋友能够学习下时间轮和时间堆。

     

    5. 很多其它内容,请前往个人文库

    http://wenku.baidu.com/p/helpylee

查看全文
  • 相关阅读:
    用户及文件权限管理
    Linux基础操作及概念
    监督学习和非监督学习
    基于仿生算法的智能系统I
    9.Dijkstra求最短路 II 堆优化的Dijkstra
    8.Dijkstra求最短路 I 朴素Dijkstra
    7.有向图的拓扑序列 拓扑排序
    6.树与图的广度优先遍历 图中点的层次
    5.树的重心 树与图的深度优先遍历
    4.八数码 BFS
  • 原文地址:https://www.cnblogs.com/ldxsuanfa/p/10549193.html
  • Copyright © 2011-2022 走看看