lighttpd io 多路复用分析

本文分析了lighttpd如何利用fdevent系统实现非阻塞IO和多路复用,探讨了select、poll、kqueue、epoll等技术,并指出epoll在高性能web服务器中的应用。lighttpd的fdevent接口设计清晰,允许用户根据系统选择不同的IO模型。

开发板推荐:天空星STM32F407VET6开发板

超高性价比 STM32主控 | 超高主频 | 一板兼容百芯 | 比赛神器 | 沉金彩色丝印

                                                csdn lidp  http://blog.csdn.net/perfectpdl



在web服务器中,主要就是向socket写数据和从socket读数据。通常,web服务器是IO密集型程序,这就要求在数据的读写上,web服务器必须能够具有很好的性能,不会因为某个socket的阻塞而致使其他socket也被阻塞,否则会大大降低服务器的性能。因此,大部分的web服务器都采用非阻塞IO进行数据的读写。lighttpd通过fdevent系统,采用类似OO中面向对象的方式将对IO事件的处理进行封装,对于不同的IO系统,提供一个统一的接口,其核心机制与libevent/libev库大同小异,都是采用了所谓的Reactor模式,也就是非阻塞IO加多路复用(non-blocking IO + IO multiplexing),lighttpd通过fdevent将各种操作系统上支持的io多路复用实现进行封装,常用的io多路复用技术包括select, poll,kqueue,epoll. select应该是最原始了,基本所有类unix系统都支持,然后是poll,poll是select的升级版,并不是所有类unix系统都支持,bsd系列没有实现,poll主要解决select对单进程最大fd数的限制,但仍然没改变其轮训的本性。kqueue 是bsd系列操作系统提供的解决select,poll的性能问题,最后是明星级的 epoll,是linux 2.6 版本以后实现的一个类kqueue的东东,流行的高性能web服务器(nginx,lighttpd),cache服务器(memcached,varnish)在linux下基本都用的epoll做io事件监听,当然,为了可移植性,大多实现都对上面各种io模型进行封装,用户可以通过配置方式灵活选择。


接下在看看lighttpd 中fdevent是怎么封装的以上各种io模型。
fdevent对外提供了io模型的通用接口,而具体实现则在相应的io模型文件中。


//统一的操作接口,与后面的函数声明对应。
     int (*reset) (struct fdevents * ev);
     void (*free) (struct fdevents * ev);
     int (*event_add) (struct fdevents * ev, int fde_ndx, int fd, int events);
     int (*event_del) (struct fdevents * ev, int fde_ndx, int fd);
     int (*event_get_revent) (struct fdevents * ev, size_t ndx);
     int (*event_get_fd) (struct fdevents * ev, size_t ndx);
     int (*event_next_fdndx) (struct fdevents * ev, int ndx);
     int (*poll) (struct fdevents * ev, int timeout_ms);
     int (*fcntl_set) (struct fdevents * ev, int fd);




上面为fdevent结构内部的函数指针,具体实现在每个io模型对应的文件中,

如 epoll实现在 文件fdevent_linux_sysepoll.c中,这体现了面向对象的设计思想。

fdevent的接口很清晰,使用过程与libevent类似,在一个闭合循环内部:


 fdevent_init :初始化 ,对于epoll,调用epoll_create

 fdevent_register ,注册某fd上发生的事件对应的回调,比如server的fd.

 fdevent_add,添加某fd事件类型(in, out), 与fdevent_register 配对使用。


while(1) {

 fdevent_poll ,等待io事件并触发上面设置的回调。

}


下面为lighttpd  初始化框架,没考虑 module及connection 建立后的状态机。


 1. network_init , 初始化socket(socket, bind, listen)

 2. fork process (初始化若干子进程)

3. fdevent_init (初始化事件triger模块,记住,fdevent在fork之后)

4. fdevent_register(注册server in事件回调)

5. 

while(!is_shutdown) {

fdevent_poll();



开发板推荐:天空星STM32F407VET6开发板

超高性价比 STM32主控 | 超高主频 | 一板兼容百芯 | 比赛神器 | 沉金彩色丝印

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值