源碼如下:
util_timer.h
#ifndef LST_TIMER
#define LST_TIMER
#include <time.h>
#include <sys/time.h>
#include <stdlib.h>
#include <signal.h>
#define BUFFER_SIZE 64
struct util_timer;
/*
struct client_data{
sockaddr_in address;
int sockfd;
char buf[BUFFER_SIZE];
util_timer * timer;
};
*/
struct util_timer{
time_t expire;
// client_data * user_data;
char *buffer;
struct util_timer *prev;
struct util_timer *next;
};
struct timer_lst{
struct util_timer * head;
struct util_timer * tail;
};
void cb_func(unsigned char *userdata);
void add_timer2(struct util_timer * timer, struct util_timer *lst_head);
void add_timer(struct util_timer *timer);
void adjust_timer(struct util_timer *timer);
void del_timer(struct util_timer * timer);
void tick();
#endif
#define LST_TIMER
#include <time.h>
#include <sys/time.h>
#include <stdlib.h>
#include <signal.h>
#define BUFFER_SIZE 64
struct util_timer;
/*
struct client_data{
sockaddr_in address;
int sockfd;
char buf[BUFFER_SIZE];
util_timer * timer;
};
*/
struct util_timer{
time_t expire;
// client_data * user_data;
char *buffer;
struct util_timer *prev;
struct util_timer *next;
};
struct timer_lst{
struct util_timer * head;
struct util_timer * tail;
};
void cb_func(unsigned char *userdata);
void add_timer2(struct util_timer * timer, struct util_timer *lst_head);
void add_timer(struct util_timer *timer);
void adjust_timer(struct util_timer *timer);
void del_timer(struct util_timer * timer);
void tick();
#endif
util_timer.c
#include "util_timer.h"
struct util_timer * head;
struct util_timer * tail;
void print_hex_ex(unsigned char *buf, int len)
{
? ? int i, n;
? ? printf(" ? ? ? ? ? ?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9 ?A ?B ?C ?D ?E ?F");
? ? n = 0;
? ? for (i=0; i<len; i++)
? ? {
? ? ? ? if (i % 0x10 == 0) {
? ? ? ? ? ? printf("\n%08Xh: ", i);
? ? ? ? }
? ? ? ? printf("%02X ", buf[i]);
? ? }
printf("\nlens:%d\n\n",len);
}
void cb_func(unsigned char *userdata){
print_hex_ex(userdata, 8);
return;
}
void add_timer2(struct util_timer * timer, struct util_timer * lst_head){
struct util_timer * prev = lst_head;
struct util_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;
}
}
void add_timer(struct util_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_timer2(timer, head);
}
void adjust_timer(struct util_timer *timer){
if(!timer){
return;
}
struct util_timer * tmp = timer->next;
if(!tmp || (timer->expire < tmp->expire)){
return;
}
if(timer == head){
head = head->next;
head->prev = NULL;
timer->next = NULL;
add_timer2(timer, head);
}else{
timer->prev->next = timer->next;
timer->next->prev = timer->prev;
add_timer2(timer, timer->next);
}
}
void del_timer(struct util_timer * timer){
if(!timer){
return;
}
if((timer == head) && (timer == tail)){
free(timer);
head = NULL;
tail = NULL;
return;
}
if(timer == head){
head = head->next;
head->prev = NULL;
free(timer);
return;
}
if(timer == tail){
tail = tail ->prev;
tail->next = NULL;
free(timer);
return;
}
timer->prev->next = timer->next;
? ? timer->next->prev = timer->prev;
free(timer);
}
void tick(){
if( !head )
? ? ?{
? ? ? ? return;
? ? ?}
? ? ?printf( "timer tick\n" );
? ? ?time_t cur = time( NULL );
? ? ?struct util_timer* tmp = head;
? ? ?while( tmp )
? ? ?{
? ? ? ? ?if( cur < tmp->expire )
? ? ? ? ?{
printf("tmp->expire is not chaoshi\n");
? ? ? ? ? ? ?break;
? ? ? ? ?}
cb_func( tmp->buffer );
? ? ? ? ?head = tmp->next;
? ? ? ? ?if( head )
? ? ? ? ?{
? ? ? ? ? ? ?head->prev = NULL;
? ? ? ? ?}
? ? ? ? ?free(tmp);
? ? ? ? ?tmp = head;
? ? ?}
}
int main(){
int i;
char *tmpbuf[5]={"aaaaaaaa","bbbbbbbb","cccccccc","dddddddd","eeeeeeee"};
head = NULL;
tail = NULL;
time_t cur = time(NULL);
for(i = 0; i<5; i++){
struct util_timer *timer = NULL ;
timer = (struct util_timer *)malloc(sizeof(struct util_timer)*1);
cur = cur + 1;
timer->expire = cur;
timer->buffer = tmpbuf[i];
add_timer(timer);
}
printf("sleep begin \n");
sleep(3);
printf("sleep end \n");
tick();
}
struct util_timer * head;
struct util_timer * tail;
void print_hex_ex(unsigned char *buf, int len)
{
? ? int i, n;
? ? printf(" ? ? ? ? ? ?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9 ?A ?B ?C ?D ?E ?F");
? ? n = 0;
? ? for (i=0; i<len; i++)
? ? {
? ? ? ? if (i % 0x10 == 0) {
? ? ? ? ? ? printf("\n%08Xh: ", i);
? ? ? ? }
? ? ? ? printf("%02X ", buf[i]);
? ? }
printf("\nlens:%d\n\n",len);
}
void cb_func(unsigned char *userdata){
print_hex_ex(userdata, 8);
return;
}
void add_timer2(struct util_timer * timer, struct util_timer * lst_head){
struct util_timer * prev = lst_head;
struct util_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;
}
}
void add_timer(struct util_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_timer2(timer, head);
}
void adjust_timer(struct util_timer *timer){
if(!timer){
return;
}
struct util_timer * tmp = timer->next;
if(!tmp || (timer->expire < tmp->expire)){
return;
}
if(timer == head){
head = head->next;
head->prev = NULL;
timer->next = NULL;
add_timer2(timer, head);
}else{
timer->prev->next = timer->next;
timer->next->prev = timer->prev;
add_timer2(timer, timer->next);
}
}
void del_timer(struct util_timer * timer){
if(!timer){
return;
}
if((timer == head) && (timer == tail)){
free(timer);
head = NULL;
tail = NULL;
return;
}
if(timer == head){
head = head->next;
head->prev = NULL;
free(timer);
return;
}
if(timer == tail){
tail = tail ->prev;
tail->next = NULL;
free(timer);
return;
}
timer->prev->next = timer->next;
? ? timer->next->prev = timer->prev;
free(timer);
}
void tick(){
if( !head )
? ? ?{
? ? ? ? return;
? ? ?}
? ? ?printf( "timer tick\n" );
? ? ?time_t cur = time( NULL );
? ? ?struct util_timer* tmp = head;
? ? ?while( tmp )
? ? ?{
? ? ? ? ?if( cur < tmp->expire )
? ? ? ? ?{
printf("tmp->expire is not chaoshi\n");
? ? ? ? ? ? ?break;
? ? ? ? ?}
cb_func( tmp->buffer );
? ? ? ? ?head = tmp->next;
? ? ? ? ?if( head )
? ? ? ? ?{
? ? ? ? ? ? ?head->prev = NULL;
? ? ? ? ?}
? ? ? ? ?free(tmp);
? ? ? ? ?tmp = head;
? ? ?}
}
int main(){
int i;
char *tmpbuf[5]={"aaaaaaaa","bbbbbbbb","cccccccc","dddddddd","eeeeeeee"};
head = NULL;
tail = NULL;
time_t cur = time(NULL);
for(i = 0; i<5; i++){
struct util_timer *timer = NULL ;
timer = (struct util_timer *)malloc(sizeof(struct util_timer)*1);
cur = cur + 1;
timer->expire = cur;
timer->buffer = tmpbuf[i];
add_timer(timer);
}
printf("sleep begin \n");
sleep(3);
printf("sleep end \n");
tick();
}
編譯gcc -o util_timer util_timer.c
運行./util_timer
輸出:
[root@hsm timer_test]# ./util_timer
sleep begin?
sleep end?
timer tick
? ? ? ? ? ? 0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9 ?A ?B ?C ?D ?E ?F
00000000h: 61 61 61 61 61 61 61 61?
lens:8
? ? ? ? ? ? 0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9 ?A ?B ?C ?D ?E ?F
00000000h: 62 62 62 62 62 62 62 62?
lens:8
? ? ? ? ? ? 0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9 ?A ?B ?C ?D ?E ?F
00000000h: 63 63 63 63 63 63 63 63?
lens:8
tmp->expire is not chaoshi
sleep begin?
sleep end?
timer tick
? ? ? ? ? ? 0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9 ?A ?B ?C ?D ?E ?F
00000000h: 61 61 61 61 61 61 61 61?
lens:8
? ? ? ? ? ? 0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9 ?A ?B ?C ?D ?E ?F
00000000h: 62 62 62 62 62 62 62 62?
lens:8
? ? ? ? ? ? 0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9 ?A ?B ?C ?D ?E ?F
00000000h: 63 63 63 63 63 63 63 63?
lens:8
tmp->expire is not chaoshi
總結:鏈表共五個節點,每個節點相差1秒,按時間大小升序排列,鏈表頭時間節點最小,依次遞增。tick函數只處理鏈表中已經超時的節點,并打印buffer里的值。當休眠3秒時,鏈表中的前3個節點已經超時,剩下的2個節點沒有超時,所以只打印前三個節點。