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

  

  

时间: 2024-08-25 03:37:26

thttpd源代码解析 定时器模块的相关文章

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-Fo

Cocos2d-x源代码解析(1)——地图模块(3)

接上一章<Cocos2d-x源代码解析(1)--地图模块(2)> 通过前面两章的分析,我们能够知道cocos将tmx的信息结构化到 CCTMXMapInfo.CCTMXTilesetInfo,CCTMXLayerInfo之中. 当中CCTMXMapInfo存储地图的信息包扩下面几块信息: - Map orientation (hexagonal, isometric or orthogonal) - Tile size - Map size - Layers (an array of TMXL

Golang中使用heap编写一个简单高效的定时器模块

定时器模块在服务端开发中非常重要,一个高性能的定时器模块能够大幅度提升引擎的运行效率.使用Golang和heap实现一个通用的定时器模块,代码来自:https://github.com/xiaonanln/goTimer 也可以查看文档:http://godoc.org/github.com/xiaonanln/goTimer,下面是完整的代码,并进行适当的注释和分析. 从性能测试结果来看,基于heap的定时器模块在效率上并不会比时间轮(TimeWheel)的实现慢多少,但是逻辑上要简单很多.

GlusterFS源代码解析 —— GlusterFS 日志

Logging.c: /* Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com> This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or

Spark技术内幕:Client,Master和Worker 通信源代码解析

Spark的Cluster Manager能够有几种部署模式: Standlone Mesos YARN EC2 Local 在向集群提交计算任务后,系统的运算模型就是Driver Program定义的SparkContext向APP Master提交,有APP Master进行计算资源的调度并终于完毕计算.具体阐述能够阅读<Spark:大数据的电花火石!>. 那么Standalone模式下,Client.Master和Worker是怎样进行通信,注冊并开启服务的呢? 1. node之间的RP

linux device tree源代码解析--转

//Based on Linux v3.14 source code Linux设备树机制(Device Tree) 一.描述 ARM Device Tree起源于OpenFirmware (OF),在过去的Linux中,arch/arm/plat-xxx和arch/arm/mach-xxx 中充斥着大量的垃圾代码,相当多数的代码只是在描述板级细节,而这些板级细节对于内核来讲,不过是垃圾,如板上的platform设备. resource.i2c_board_info.spi_board_info

实时捕捉以太网原始数据包(PacketRawEthernetMonitor)----Kithara RTS工程源代码解析

本文以windows实时拓展Kithara RTS安装目录下的smp文件夹内的PacketRawEthernetMonitor工程源码为例,该源码实现了一个简单的网络监视程序,可以实时监测网卡接收的原始数据.该工程主要使用了Kernel,Packet模块,有三个函数组成:主函数runSample,回调函数_callBack,线程_recvThread,_callBack和_recvThread之间存在着同步关系,线程_recvThread运行时会堵塞等待事件,回调函数设置该事件后线程才能继续运行

Asterisk 源代码解析之SIP呼叫

下图是asterisk的呼叫流程图: 我们以sip的呼叫过程为例来描述,其他channel的呼叫过程基本类似. Astersik下注册的sip用户主动发起一个呼叫的函数调用过程(incoming)如下: do_monitor->sipsock_read->handle_request->handle_request_invite->sip_new/ast_pbx_start->pbx_thread->__ast_pbx_run -> ast_spawn_exten

Android源代码解析之(十三)--&amp;gt;apk安装流程

转载请标明出处:一片枫叶的专栏 上一篇文章中给大家分析了一下android系统启动之后调用PackageManagerService服务并解析系统特定文件夹.解析apk文件并安装的过程,这个安装过程实际上是没有图形界面的,底层调用的是我们平时比較熟悉的adb命令,那么我们平时安装apk文件的时候大部分是都过图形界面安装的,那么这样的方式安装apk详细的流程是如何的呢? 本文我们就来详细看一下apk的详细安装过程,通过本文的学习希望帮助大家大概的了解到Android系统安装Apk文件的基本流程.好