標籤:remove timeout timers center upd malloc set 使用者 檔案流
thttpd原始碼解析 定時器模組
- thttpd是很輕量級的httpserver,可運行檔案僅50kB。名稱中的第一個
t表示tiny, turbo, 或throttling
- 與lighttpd、memcached、redis相比很小巧,僅有不到8k行,而後三者大小分別為:60k,13k,86k
- 支援HTTP/1.1和CGI;採用IO複用實現,單線程,可移植;實現了基於URL的檔案流量限制功能
- 特別適用於大量待用資料訪問的情境,片儲存
- 2004年已經停止維護,有一個關於X-Forwarded-For HTTP header的bug。後來出現stthhpd基於此項目
- 效能比較參考對照
- 本文針對timer模組進行分析
timer模組
- 包含timer.h,timer.c兩個檔案
- 使用全域開放式散列表。預設大小67,每一個hash節點上的值依照時間順序排列
- ClientData定義例如以下:
typedef union { void* p; int i; long l; } ClientData;
- TimerProc型別宣告例如以下:
void TimerProc( ClientData client_data, struct timeval* nowP )。函數將在定時器逾時時調用
- Timer結構定義例如以下:
typedef struct TimerStruct { TimerProc* timer_proc; ClientData client_data; long msecs; int periodic; struct timeval time; struct TimerStruct* prev; struct TimerStruct* next; int hash; } Timer;
void tmr_init( void )
Timer* tmr_create( struct timeval* nowP, TimerProc* timer_proc, ClientData client_data, long msecs, int periodic )
- 建立一個定時器,指定是一次性/周期性,增加散列表
- 定時器的時間設定為nowP的時刻加上msecs毫秒之後。若nowP為0,設定為當前時刻加上msecs毫秒
timeval* tmr_timeout( struct timeval* nowP )
- 返回到下次觸發的時間間隔
- 調用tmr_mstimeout得到
tmr_mstimeout( struct timeval* nowP )
- 返回到下次觸發時間間隔的毫秒數。即從nowP開始,經過多少毫秒hash表中會有一個定時器觸發
- 由於hash表中的每一個鏈表都是有序的,遍曆一次hash表就可以
void tmr_run( struct timeval* nowP )
- 遍曆hash表。假設定時器沒有逾時,調用timer_proc
- 假設定時器是周期性的,則調用後時間後延msecs,假設是非周期性的,則調用tmr_cancel去除
void tmr_reset( struct timeval* nowP, Timer* timer )
- 又一次開始執行定時器。時鐘設定為目前時間nowP加上定時時間長度
void tmr_cancel( Timer* timer )
- 釋放定時器,因為tmr_run中對全部非周期性定時器都已經調用tmr_cancel,使用者無需再自己對非周期定時器調用
- 將timers增加free_timers鏈表,節省free和malloc的開銷,相當於一個緩衝池
void tmr_cleanup( void )
- 清空定時器包。釋放全部沒用的記憶體:free_timers鏈表
void tmr_destroy( void )
- 調用tmr_cancel釋放全部定時器,為退出做準備,
void tmr_logstats( long secs )
- 產生調試log資訊,記錄當前已指派、使用中、free的定時器個數
- 操作hash表的靜態函數
- hash:由
(time.tv_sec ^ time.tv_usec) % 67得到hash值
- l_add:插入一個定時器
- l_remove:移除一個定時器
- re_sort:定時器結構體含有之前的hash值,假設定時器的值改變,移除後又一次計算hash,插入到正確的位置
timer模組的使用
- 在main函數中使用類timer模組
- 調用tmr_init初始化
- 建立周期為OCCASIONAL_TIME的周期定時器,回呼函數為occasional
- 建立周期為5s的周期定時器,回呼函數為idle
- 建立周期為THROTTLE_TIME的周期定時器。回調update_throttles
- 建立周期為STATS_TIME的周期定時器,回調show_stats
- 在主要事件處理迴圈中:
- 假設沒有socket發生事件。調用一次tmr_run,continue
- 假設有新串連,continue。以保證新串連優先得到處理
- 假設有事件發生,則處理事件
- 執行一次tmr_run
- occasional
- 調用mmc_cleanup
- 調用tmr_cleanup,清除沒用的定時器記憶體池
- 設定watchdog_flag = 1,使watchdog知道程式仍在執行
- idle
- update_throttles 更新流量控制
- show_stats
轉載請註明Focustc,部落格地址為http://blog.csdn.net/caozhk。原文連結為點擊開啟
thttpd原始碼解析 定時器模組