zoukankan      html  css  js  c++  java
  • thttpd源代码解析 定时器模块

    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 )
      • 初始化定时器包。即定时器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。原文链接为点击打开

      
      
  • 相关阅读:
    Delphi公用函数单元
    Delphi XE5 for Android (十一)
    Delphi XE5 for Android (十)
    Delphi XE5 for Android (九)
    Delphi XE5 for Android (八)
    Delphi XE5 for Android (七)
    Delphi XE5 for Android (五)
    Delphi XE5 for Android (四)
    Delphi XE5 for Android (三)
    Delphi XE5 for Android (二)
  • 原文地址:https://www.cnblogs.com/liguangsunls/p/6800504.html
Copyright © 2011-2022 走看看