码迷,mamicode.com
首页 > 其他好文 > 详细

Nginx:异步非阻塞IO

时间:2015-10-31 22:50:55      阅读:478      评论:0      收藏:0      [点我收藏+]

标签:

在使用socket编程中,经常会看到阻塞、非阻塞、同步、异步,那么它们之间到底有什么关系跟区别呢?

本次将那Nginx的异步非阻塞的事件驱动模型来解释一下它们之间的关系。

 

阻塞IO

在linux中,默认所有socket都是阻塞的。

这意味着使用该socket调用诸如recv的函数时,在没有数据到达之前,该函数将不会返回,导致线程被阻塞,直到数据到达。

 

非阻塞IO

我们可以使用fcntl把socket设置为非阻塞的。

这意味着使用该socket调用诸如recv的函数时,该函数将立刻返回,可以根据返回值来确定是否有数据到达。

 

相信阻塞/非阻塞IO的大家都非常的清楚,本次主要说的是同步IO跟异步IO之间的区别。

首先要说的是,同步/异步只是跟具体实现有关,就是说非阻塞的必定是异步的的说法是错误的,它们之间并没有确定的关系。

 

同步IO

一般来说,我们调用的函数都是同步的。

何为同步呢?就是说我们调用了一个函数,在该函数返回之后就说明该函数要做的东西已经完成了。

这是我们一般的做法,例如说我们调用recv接收数据,在该函数返回之后,就代表我们已经接收好数据了。

 

异步IO

异步IO大概可以这样理解:

我们调用一个函数,在该函数返回之后其实该函数要完成的事情还没真正完成,而是被托管到其它地方了(如Nginx的事件驱动)。

可见该函数的功能并不是立刻完成的(但是最终会由托管的模块去完成)。

可能读者会有这样的疑问:异步IO到底是怎么样实现的呢?它有什么应用呢?下面将拿Nginx的事件驱动模型来解决这些问题。

 

 

 

异步非阻塞IO的应用

拿一个比较容易理解的例子:

在处理HTTP请求的时候,如果要忽略请求包体的内容(我们必须接收包体,但是不做处理),我们会ngx_discard_reqeust_body函数。

忽略请求包体的过程可能比较长,但是我们不需要理会包体的内容(该函数返回的内容我们并不在意),因此该函数是异步非阻塞的:

这样,在调用该函数之后我们可以继续执行下面的代码,而接收并忽略包体的动作则托管给事件驱动去完成。

 

 

异步非阻塞IO在Nginx的实现

Nginx的高并发来源于其异步非阻塞的事件驱动,下面将对Nginx基于epoll的事件驱动模型来说明。

 

关于epoll的使用方法跟Nginx事件驱动模型可以查看 http://www.cnblogs.com/runnyu/p/4914698.html 的前面两部分,这里将不做详细说明。

可见,Nginx主循环会调用ngx_epoll_process_events方法,而该方法则调用epoll_wait来获取事件并且处理事件。

我们只要调用epoll_ctl向epoll中添加或者删除事件(托管事件),Nginx事件驱动就会帮我们在事件准备好的时候处理相应的事件了。

Nginx:异步非阻塞IO

标签:

原文地址:http://www.cnblogs.com/runnyu/p/4926354.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!