thttpd源碼解析 定時器模塊

thttpd源碼解析 定時器模塊

  • thttpd是非常輕量級的http服務器,可執行文件僅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 )
    • 初始化定時器包,即定時器hash表
  • 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
    • 調用函數logstats,記錄信息

  
  

轉載請註明作者:Focustc,博客地址爲http://blog.csdn.net/caozhk,原文鏈接爲點擊打開

  
  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章