linux C 基于鏈表鏈的定時器

源碼如下:
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

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();
}

編譯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

總結:鏈表共五個節點,每個節點相差1秒,按時間大小升序排列,鏈表頭時間節點最小,依次遞增。tick函數只處理鏈表中已經超時的節點,并打印buffer里的值。當休眠3秒時,鏈表中的前3個節點已經超時,剩下的2個節點沒有超時,所以只打印前三個節點。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/385034.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/385034.shtml
英文地址,請注明出處:http://en.pswp.cn/news/385034.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

libevent學習筆記 一、基礎知識

一、libevent是什么libevent是一個輕量級的開源的高性能的事件觸發的網絡庫&#xff0c;適用于windows、linux、bsd等多種平臺&#xff0c;內部使用select、epoll、kqueue等系統調用管理事件機制。它被眾多的開源項目使用&#xff0c;例如大名鼎鼎的memcached等。特點&#xff…

漢字逆置

在計算機中&#xff0c;一個漢字用無法用1個字節來表示 #include<stdio.h> int main() {char buf[256] "你好";int len 0;while(buf[len]);len--;printf("%d\n",len);// 4一個漢字兩個字節 //printf("%p\n",buf);return 0; } 在windows下…

libevent項目分析(一) -- 準備階段

項目的簡介 我理解libevent是一個輕量級的&#xff0c;跨平臺高效的&#xff08;C語言實現&#xff09;事件驅動庫&#xff0c;類似于ACE項目中的ACE_Reactor&#xff0c;它實現了網絡通訊套接口I/O事件&#xff0c;定時器事件&#xff0c;信號事件的監聽和事件處理函數回調機制…

混合字符串字符數統計

因為漢字占一個以上字節&#xff0c;如何統計一個既有漢字又有字母的字符串呢&#xff1f; 漢字在計算機中的ASCII是以負數來與其他普通字符的ASCII區分的。 #include<stdio.h> int main() {char buf[256] "你好世界";printf("%d\n",buf[0]); //-60…

清除字符串空格

1.清除字符串中右邊的空格 從字符串尾部開始&#xff0c;找到非空格處&#xff0c;將下一個字符置為0即可。 //清除右邊空格 #include<stdio.h> int main() {char buf[] "hello world ";int len 0;//calculate the length of stringwhile(buf[len]);le…

淺談auto_ptr智能指針

引入智能指針&#xff1a;智能指針的實現原理&#xff1a; 資源分配即初始化RAII(Resource Acquisition Is Initialization)&#xff1a; 定義一個類來封裝資源的分配和釋放&#xff0c;在構造函數完成資源的分配和初始化&#xff0c;在析構函數完成資源的清理&#xff0c;可…

隨機數

隨機數產生器rand(),頭文件為#include<stdlib.h> #include<stdio.h> #include<stdlib.h>int main() {int value;int i;for(i 0; i < 10; i){value rand();printf("value %d\n",value);}return 0; } 運行結果&#xff1a; value 41 value 1…

多重繼承之虛繼承(主要是為了解決產生的數據冗余問題)

虛繼承 是面向對象編程中的一種技術&#xff0c;是指一個指定的基類&#xff0c;在繼承體系結構中&#xff0c;將其成員數據實例共享給也從這個基類型直接或間接派生的其它類。形式&#xff1a;在繼承定義中包含了virtual關鍵字的繼承關系&#xff0c;如下圖中&#xff0c;類A就…

通過syslog接收遠程日志

通過syslog接收遠程日志通過syslog接收遠程主機的日志&#xff0c;需要做一些環境配置。客戶機A通過syslog將日志信息發送到服務主機B&#xff08;或稱日志采集服務器&#xff09;。以下說明配置過程&#xff08;我的實驗環境是&#xff0c;客戶機A&#xff1a;Solaris 10&…

linux syslog服務器配置,自動發日志到另一臺日志服務器

1.客戶端:168.1.20.66修改/etc/syslog.conf 添加syslog.info 168.1.80.302.日志服務器:168.1.80.30修改/etc/sysconf/syslog 修改SYSLOGD_OPTIONS為 "-r -x -m 0" #-r表示允許接收外來的消息&#xff0c;-x表示不解析DNS, #-m 0表示時間戳標記間隔,如果指定只接…

Make文件(一)

基本規則&#xff1a; 目標&#xff1a;依賴 &#xff08;tab&#xff09;規則 目標&#xff1a;需要生成的目標文件 依賴&#xff1a;生成該目標所需的一些文件 規則&#xff1a;由依賴文件生成目標文件的手段 tab&#xff1a;每條規則前必須以tab開頭&#xff0c;使用空格不行…

移植驅動完畢后加載時的version magic報錯原因以及解決辦法

History:2012-02-17Author:yingru移植rt3070的AP驅動到裝有fedora14的PC機上時&#xff0c;模塊編譯完畢后&#xff0c;加載時提示invalid module format。PC機環境介紹&#xff1a;內核版本&#xff1a;2.6.35.6-45.fc14.i686命令行輸入dmesg查看最后的日志&#xff0c;發現如…

/proc 虛擬文件系統(實例)

Linux下有一個神奇的目錄/proc&#xff0c;經常會運行 cat /proc/cpuinfo 命令查看cpu信息&#xff0c;/proc下的確有cpuinfo文件&#xff0c;但是這個文件不是物理存在的&#xff0c;是軟件虛擬出來的&#xff0c;與普通文件不同&#xff0c;該文件是動態的。通過/proc可以實現…

內核模塊中對文件的讀寫

平時網絡部分的東西碰的多些&#xff0c;這塊一開始還真不知道怎么寫&#xff0c;因為肯定和在用戶空間下是不同的。google過后&#xff0c;得到以下答案。一般可以用兩種方法&#xff1a;第一種是用系統調用。第二種方法是filp->open()等函數。下面分別來說下這兩種方法。1…

Makefile文件試錯

1成功&#xff1a; src $(wildcard ./*cpp) obj $(patsubst %.cpp,%.o ,$(src))target test$(target) : $(obj)g $(obj) -o $(target) -I/usr/include/mysql -L/usr/lib/mysql/ -lmysqlclient %.o: %.cppg -c $< -o $ -I/usr/include/mysql -L/usr/lib/mysql/ -lmysql…

內核定時器timer_list使用

Linux內核中提供了timer使用的API&#xff0c;做一個簡單的記要。 1. 包含的頭文件&#xff1a;linux/timer.h 2. 數據類型&#xff1a;struct timer_list; 包含的主要成員&#xff1a; a. data:傳遞到超時處理函數的參數&#xff0c;主要在多個定時器同時使用時&#xff0c;區…

內存四區

1.代碼區&#xff1a; 代碼區Code&#xff0c;程序被操作系統加載到內存的時候&#xff0c;所有的可執行代碼都加載到代碼區&#xff0c;也叫代碼段&#xff0c;這塊內存是不可以在運行期間修改的。 2. 靜態區 所有的全局變量以及程序中的靜態變量都存儲在靜態區。 #include<…

最高效的進(線)程間通信機制--eventfd

我們常用的進程&#xff08;線程&#xff09;間通信機制有管道&#xff0c;信號&#xff0c;消息隊列&#xff0c;信號量&#xff0c;共享內存&#xff0c;socket等等&#xff0c;其中主要作為進程&#xff08;線程&#xff09;間通知/等待的有管道pipe和socketpair。線程還有特…

malloc,calloc,realloc

與堆操作相關的兩個函數 malloc #include<stdio.h> #include<stdlib.h> #include<string.h>int main() {char *p malloc(10); //內存隨機&#xff0c;未做處理int i;for(i 0; i < 10: i){printf(“%d “,p[i]);} free(p);return 0; } 運行結果&…

Linux內核同步機制之completion

內核編程中常見的一種模式是&#xff0c;在當前線程之外初始化某個活動&#xff0c;然后等待該活動的結束。這個活動可能是&#xff0c;創建一個新的內核線程或者新的用戶空間進程、對一個已有進程的某個請求&#xff0c;或者某種類型的硬件動作&#xff0c;等等。在這種情況下…