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,插入到正确的位置
- 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,原文链接为点击打开
thttpd源码解析 定时器模块相关推荐
- libev源码解析——定时器监视器和组织形式
我们先看下定时器监视器的数据结构.(转载请指明出于breaksoftware的csdn博客) /* invoked after a specific time, repeatable (based o ...
- libev源码解析——定时器原理
本文将回答<libev源码解析--I/O模型>中抛出的两个问题.(转载请指明出于breaksoftware的csdn博客) 对于问题1:为什么backend_poll函数需要指定超时?我们 ...
- 以太坊Geth 共识算法源码解析
共识算法 目前以太坊中有两个公式算法的实现,分别为clique和ethash.其中clique是PoA共识的实现,ethash是PoW共识的实现,其相应的代码位于go-ethereum/consens ...
- Libuv源码解析 - uv_loop整个初始化模块
Libuv源码解析 - uv_loop整个初始化模块 loop_default_loop static uv_loop_t default_loop_struct; static uv_loop_t* ...
- jQuery源码解析(架构与依赖模块)
jQuery设计理念 引用百科的介绍: jQuery是继prototype之后又一个优秀的Javascript框架.它是轻量级的js库 ,它兼容CSS3,还兼容各种浏览器(IE 6.0+, FF 1. ...
- jQuery源码解析(架构与依赖模块)第一章 理解架构
1-1 jQuery设计理念 引用百科的介绍: jQuery是继prototype之后又一个优秀的Javascript框架.它是轻量级的js库 ,它兼容CSS3,还兼容各种浏览器(IE 6.0+, F ...
- python处理回显_Python中getpass模块无回显输入源码解析
本文主要讨论了python中getpass模块的相关内容,具体如下. getpass模块 昨天跟学弟吹牛b安利Python标准库官方文档的时候偶然发现了这个模块.仔细一看内容挺少的,只有两个主要api ...
- erlang下lists模块sort(排序)方法源码解析(二)
上接erlang下lists模块sort(排序)方法源码解析(一),到目前为止,list列表已经被分割成N个列表,而且每个列表的元素是有序的(从大到小) 下面我们重点来看看mergel和rmergel ...
- C51单片机与PCF8591模块的交互:C语言源码解析
目录 1. PCF8591模块简介 2. C51单片机与PCF8591的连接 3. C51单片机与PCF8591的C语言源码解析 4. 用法示例 5. 总结 6. 参考文献 在微控制器的世界中,C51 ...
最新文章
- Eclipse生成jar文件
- python保存内容到文件(text、json、csv)
- lottie 导出html,Lottie Web动效基本原理
- 「SDOI2016」储能表(数位dp)
- JavaScript函数调用规则
- 7. Decorator pattern(装饰器模式)
- ansys与solidworks关联失败,将SolidWorks模型导入ansys划分网格总是提示错误
- 基于51单片机的智能温控风扇
- 接口文档生成工具ApiPost挺好用
- LeetCode K站中转内最便宜的航班(回溯法、动态规划)
- 利率里面的BP是什么意思,bp是什么意思贷款利率
- Exp2 后门原理与实践 20164302 王一帆
- 资深程序员雷总对代码的执念
- BT源代码学习心得(六):跟踪服务器(Tracker)的代码分析(初始化)
- catflag Crypto KeyBoard
- 为设计指定输入端口驱动强度:set_driving_cell、set_drive 和set_input_transition
- 基于单片机烟雾及温度报警器-火灾监测-毕设课设资料
- java实现打印机打印发票路径
- 六 系统可靠性分析与设计
- 网站搭建(简洁版本)
热门文章
- python 录入数据不重复_python Django批量导入不重复数据
- day19 java数组的常用算法和排序
- 利用CSS使元素在水平方向或水平,竖直同时居中
- java list 重复对象_list集合去除重复对象的实现
- linux查看文件的方法,查看linux文件的方法
- php 检查路劲是否存在,php 检查文件或目录是否存在代码总结
- HTML搜索框中加入提示文字,HTML 5 input placeholder 属性 实现搜索框提示文字点击输入后消失 - 尚码园...
- zblog php 安装,zblog教程:Z-BlogPHP如何安装
- ajax 表格删除,jQuery AJAX删除只捕获第一个表格
- python获取绝对路径_python - OS(一)获取绝对路径