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。原文链接为点击打开

      
      
  • 相关阅读:
    死锁
    Notepad++源代码阅读——窗口封装与继承
    Notepad++源代码阅读——窗口元素组织与布局
    选择问题(selection problem)
    插入排序 | 冒泡排序 | 希尔排序 | 堆排序 | 快速排序 | 选择排序 | 归并排序
    编程之美2014---大神与三位小伙伴
    ulimit 修改 open files & core
    tmux手记
    匿名访问windows server 2008 R2 文件服务器的共享
    WINDOWS系统变量
  • 原文地址:https://www.cnblogs.com/liguangsunls/p/6800504.html
Copyright © 2011-2022 走看看