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
得到hash值
^ time.tv_usec) % 67 - 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源代码解析 定时器模块的更多相关文章
- Cocos2d-x源代码解析(1)——地图模块(3)
接上一章<Cocos2d-x源代码解析(1)--地图模块(2)> 通过前面两章的分析,我们能够知道cocos将tmx的信息结构化到 CCTMXMapInfo.CCTMXTilesetInf ...
- Android xUtils3源代码解析之网络模块
本文已授权微信公众号<非著名程序猿>原创首发,转载请务必注明出处. xUtils3源代码解析系列 一. Android xUtils3源代码解析之网络模块 二. Android xUtil ...
- 《nginx源代码解析》系列分享专栏
<nginx源代码解析>系列分享专栏 解析nginx源代码,从main函数开始,一步步解读nginx运行原理,同时进行nginx第三方模块的开发,努力做到知其然,知其所以然 <ngi ...
- linux device tree源代码解析--转
//Based on Linux v3.14 source code Linux设备树机制(Device Tree) 一.描述 ARM Device Tree起源于OpenFirmware (OF), ...
- Android源代码解析之(十三)-->apk安装流程
转载请标明出处:一片枫叶的专栏 上一篇文章中给大家分析了一下android系统启动之后调用PackageManagerService服务并解析系统特定文件夹.解析apk文件并安装的过程,这个安装过程实 ...
- Spark技术内幕:Client,Master和Worker 通信源代码解析
Spark的Cluster Manager能够有几种部署模式: Standlone Mesos YARN EC2 Local 在向集群提交计算任务后,系统的运算模型就是Driver Program定义 ...
- Spring源代码解析
Spring源代码解析(一):IOC容器:http://www.iteye.com/topic/86339 Spring源代码解析(二):IoC容器在Web容器中的启动:http://www.itey ...
- python解析xml模块封装代码
在python中解析xml文件的模块用法,以及对模块封装的方法.原文转自:http://www.jbxue.com/article/16586.html 有如下的xml文件:<?xml vers ...
- Arrays.sort源代码解析
Java Arrays.sort源代码解析 Java Arrays中提供了对所有类型的排序.其中主要分为Primitive(8种基本类型)和Object两大类. 基本类型:采用调优的快速排序: 对象类 ...
随机推荐
- TCP/IP(域名DNS)
域名是不带http://的. 有DNS就能解析域名,只要联网,不用担心你的域名和IP无法映射起来. 当然,域名和IP的映射也可以通过本地hosts文件(优先于DNS)添加.C:\Windows\Sys ...
- LFYZOJ 104 Counting Swaps
题解 #include <iostream> #include <cstdio> #include <algorithm> #include <cmath&g ...
- 【NOIP2016练习】T1 string (计数)
题意: 思路: ; ..]of int64; n,k,i:longint; ans,x,y:int64; s,t:ansistring; function c(x,y:longint):int64; ...
- 本地安装Sass,Compass
使用本地的gem文件来安装Sass和Compass. 1.安装Ruby http://rubyinstaller.org/downloads/ 下载之后双击安装即可,在安装过程中可以选择“Add Ru ...
- 理解webpack中的devTool的配置项
2.1. eval eval 会将每一个module模块,执行eval,执行后不会生成sourcemap文件,仅仅是在每一个模块后,增加sourceURL来关联模块处理前后对应的关系.在webpac ...
- 常用工具篇(二)死链接扫描工具–Xenu
一个网站上线一段时间之后,可能出现很多的死链接,死链接就是那些打不开的链接,或者是请求是404的,可能是因为有的文件位置移动了,或者有的功能不好使了,可能会影响我们网的功能,我们就要隔一阵扫描一下网站 ...
- Codeforces 946 A.Partition
随便写写,然后写D的题解. A. Partition time limit per test 1 second memory limit per test 256 megabytes input ...
- BZOJ 4568 [Scoi2016]幸运数字(树链剖分 + 异或线性基)
题目链接 BZOJ 4568 考虑树链剖分+线段树维护每一段区域的异或线性基 对于每个询问,求出该点集的异或线性基.然后求一下这个线性基里面能异或出的最大值即可. #include <bits ...
- Jenkins解决Host key verification failed
1.在没有做任何操作时,是这样报错的 a.在任务中配置远程执行命令 rsync -raz --delete --progress target/testweb-v1.1.jar root@10.0 ...
- Nessus虚拟机的几个问题解决办法
1.使用ppp的校园网或者家庭宽带无法通过桥接上网. 这时要把这俩网卡变成NAT模式就行. 2.国外下载插件包(或者过慢). 我这里贡献个高速链接.base64,懂得自然懂. c3NyOi8vTkRj ...