Nginx源码分析(6)

Nginx具有一系列的模块,包括HTTP模块,核心模块和mail模块等。简要分析一下一些具有代表性模块的原理。

event模块

event模块的主要功能是监听accept后建立的连接,对读写事件进行添加删除。事件处理模型和Nginx的非阻塞IO模型结合在一起使用。当IO可读可写的时候,相应的读写时间就会被唤醒,此时就会去处理事件的回调函数。

对于Linux,Nginx使用的是epollepollpoolselect的增强版本。

select,poll,epoll都是IO多路复用的机制。I/O多路复用就通过一种机制,可以监视多个描述符(fd),一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。但select,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的,而异步I/O则无需自己负责进行读写,异步I/O的实现会负责把数据从内核拷贝到用户空间。

所以epoll本质是同步IO + 阻塞的。

select模型的调用流程如下:

输入图片说明

epoll对select模型和poll模型有诸多改进。

select用O(n)的效率不断地去查看那些fd,效率太低。而epoll通过在内核中提供callback机制的方式,在内部使用链表把O(n)降到了O(1),讨论参见SO

我们看看怎么实现callback机制的。

输入图片说明

当为一个用户建立一个socket连接时,调用epoll的current进程会加入到驱动的wait_queue中。当其它用户连接时,进行同样的处理。所以current进程在所有驱动的等待队列中。

当IO没有就绪,调用read函数会阻塞在这一步。一旦只要有一个用户连接的IO就绪,current进程就会被唤醒。

与select相比,epoll加入了callback这个hock,记录了这个唤醒者,避免了在current进程醒着的时候查询到底是谁唤醒了我。

##timer模块 先看一段代码,timer什么时候起作用。

void Request::run()
{
    keep_alive_timer = new QTimer();
    if (s_keep_alive_enable)
    {
        keep_alive = s_keep_alive_default;
        keep_alive_timeout = s_keep_alive_timeout * 1000;// the wait time
        connect(keep_alive_timer, SIGNAL(timeout()), this, SLOT(onTimeout()));
        keep_alive_timer->setSingleShot(true);
        keep_alive_timer->setInterval(keep_alive_timeout);
        keep_alive_timer->start();
    }
    //a new thread
    socket = new QTcpSocket();
    if (!socket->setSocketDescriptor(socketDescriptor))
        return;
    connect(socket, SIGNAL(readyRead()), this, SLOT(onReadyRead()), Qt::DirectConnection);
    connect(socket, SIGNAL(disconnected()), this, SLOT(onDisconnected()), Qt::DirectConnection);
    exec();
}

代码出自一个简单的http服务器。它新建了一个定时器,然后计算自连接开始后的时间。主要用来判断连接是否timeout。

Nginx使用红黑树来构造定时器。定时器的机制就是,二叉树的值是其超时时间,每次查找二叉树的最小值,如果最小值已经过期,就删除该节点,然后继续查找,直到所有超时节点都被删除。我们知道,自平衡二叉搜索树rbtree的树节点中,最左边叶子节点(或根节点)所代表的那个定时器的超时时间是最小的,因此只需要O(1)时间删除它就可以。

输入图片说明

##参考

http://www.cnblogs.com/Anker/p/3265058.html

http://www.cnblogs.com/Anker/p/3254269.html

http://www.pento.cn/pin/31146170

http://blog.csdn.net/ce123_zhouwei/article/details/8459730

http://blog.csdn.net/v_july_v/article/details/6105630

转载于:https://my.oschina.net/lvyi/blog/424367

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值