node js异步IO机制

同步和异步的概念描述的是用户线程与内核的交互方式:同步是指用户线程发起IO请求后需要等待或者轮询内核IO操作完成后才能继续执行;而异步是指用户线程发起IO请求后仍继续执行,当内核IO操作完成后会通知用户线程,或者调用用户线程注册的回调函数。

阻塞和非阻塞的概念描述的是用户线程调用内核IO操作的方式:阻塞是指IO操作需要彻底完成后才返回到用户空间;而非阻塞是指IO操作被调用后立即返回给用户一个状态值,无需等到IO操作彻底完成。

node js的异步I/O是它的一个重要功能,为了讲清楚这个机制,先说一下操作系统内核对于I/O的处理方式:阻塞I/O和非阻塞I/O

阻塞I/O的特点是调用之后一定要等到这个I/O的所有动作都完成后,调用才结束返回。在这期间,CPU的其它所有运算都要停滞,因此阻塞I/O使CPU等待I/O,浪费了CPU资源。

非阻塞I/O的特点就是调用之后,立即结束返回,这样,CPU就不会因为要等待I/O结束而浪费计算资源。但是,由于非阻塞I/O会立即返回,返回时完整的I/O过程并没有完成,所以返回的不是期望的I/O数据,而仅仅是当前调用的状态。所以,为了获取期望的数据,系统就要通过轮询去确定这个I/O是否完成。

从以上的描述可以看出,阻塞I/O需要系统等待I/O完成,非阻塞I/O则需要系统去轮询这个I/O是否完成,在这个层面node js的异步I/O更接近于非阻塞I/O。确切地说,node js是在非阻塞I/O的基础上,用更高效的方法代替轮询这个机制,从而达到了它称之为的异步I/O的功能。下面介绍几种不同的轮询方式:

直接轮询:它是最原始、效率最低的一种轮询方式,它通过重复调用来检查I/O的完成状态。


1

2

3

4

5

6


while true {

  for i in stream[]: {

    if i has data

      read until unavailable

  }

}

爱创课堂--专业前端技术培训

                          年薪30万不是梦

select:比较直接轮询,select使用了一个代理来检测多个I/O的状态,如果I/O还没完成,就会阻塞掉这个处理I/O的线程,使得CPU通过调度处理别的线程,当有I/O完成时,再唤醒这个线程,让程序轮询一遍所有的I/O流,找到完成的I/O并进行下一步的处理。


1

2

3

4

5

6

7


while true {

  select(streams[])

  for i in streams[] {

    if i has data

      read until unavailable

  }

}

epoll:相比于select,epoll能把那些I/O完成了哪些事件也通知给我们,因此程序就不需要再轮询一遍所有的I/O流了。


1

2

3

4

5

6

7


epollfd = epoll_create()

while true {

  active_stream[] = epoll_wait(epollfd)

  for i in active_stream[] {

    read or write till unavailable

  }

}

node js异步I/O:

异步I/O理想的状态就是应用程序发起非阻塞调用,无序通过遍历或者事件唤醒等方式轮询,直接处理下一个任务,只需在I/O完成后通过信号或者回调函数将数据传递给应用程序即可。为了实现这个功能,node采用了线程池和回调函数这两个技术。

首先,node里有一个观察者,和一个采用生产者/消费者的模型的事件循环,各种I/O请求作为生产者被传递到观察者那里,然后事件循环从观察者出取出事件,进行下一步处理。

事件循环里取出的事件,必须伴随着事件完成的回调函数


1

2

3

4


fs.open=(path,flags,mode,callback){

...

callback()

}
 

在取出事件之后,node立即返回,执行当前任务的后续任务。而这个I/O时间和它的回调函数一起,被打包送入系统的线程池,然后后续的I/O将由线程池中的线程处理。

最后,node的观察者会提取线程池中完成的I/O获得的数据,并调用它返回的回调函数,来执行整个I/O的回调。至此,node js的异步I/O结束。其中,我认为node js异步I/O最大的特点就是回调函数是由操作系统触发的,而不是由程序触发的。

时间: 2024-10-05 23:27:00

node js异步IO机制的相关文章

Node.js异步IO

为什么要异步I/O? 从用户体验角度讲,异步IO可以消除UI阻塞,快速响应资源 JavaScript是单线程的,它与UI渲染共用一个线程.所以在JavaScript执行的时候,UI渲染将处于停顿的状态,用户体验较差.而异步请求可以在下载资源的时候,JavaScript和UI渲染都同时执行,消除UI阻塞,降低响应资源需要的时间开销. 假如一个资源来自两个不同位置的数据的返回,第一个资源需要M毫秒的耗时,第二个资源需要N毫秒的耗时.当采用同步的方式,总耗时为(M+N)毫秒,代码大致如下: //耗时为

深入理解node.js异步编程

1. 概述目前开源社区最火热的技术当属Node.js莫属了,作为使用Javascript为主要开发语言的服务器端编程技术和平台,一开始就注定会引人瞩目. 当然能够吸引众人的目光,肯定不是三教九流之辈,必然拥有独特的优势和魅力,才能引起群猿追逐.其中当属异步IO和事件编程模型,本文据Node.js的异步IO和事件编程做深入分析. ##2. 什么是异步同步和异步是一个比较早的概念,大抵在操作系统发明时应该就出现了.举一个最简单的生活中的例子,比如发短信的情况会比较好说明他们的区别:同步:正在处于苦逼

Node.js异步处理CPU密集型任务

Node.js擅长数据密集型实时(data-intensive real-time)交互的应用场景.然而数据密集型实时应用程序并不是只有I/O密集型任务,当碰到CPU密集型任务时,比如要对数据加解密(node.bcrypt.js),数据压缩和解压(node-tar),或者要根据用户的身份对图片做些个性化处理,在这些场景下,主线程致力于做复杂的CPU计算,IO请求队列中的任务就被阻塞. Node.js主线程的event loop在处理所有的任务/事件时,都是沿着事件队列顺序执行的,所以在其中任何一

转:Node.js异步处理CPU密集型任务的新思路

原文来自于:http://www.infoq.com/cn/articles/new-idea-of-nodejs-asynchronous-processing-tasks?utm_source=infoq&utm_medium=popular_links_homepage Node.js擅长数据密集型实时(data-intensive real-time)交互的应用场景.然而数据密集型实时应用程序并不是只有I/O密集型任务,当碰到CPU密集型任务时,比如要对数据加解密(node.bcrypt

使用Node.js+Socket.IO搭建WebSocket实时应用【转载】

原文:http://www.jianshu.com/p/d9b1273a93fd Web领域的实时推送技术,也被称作Realtime技术.这种技术要达到的目的是让用户不需要刷新浏览器就可以获得实时更新.它有着广泛的应用场景,比如在线聊天室.在线客服系统.评论系统.WebIM等. WebSocket简介 谈到Web实时推送,就不得不说WebSocket.在WebSocket出现之前,很多网站为了实现实时推送技术,通常采用的方案是轮询(Polling)和Comet技术,Comet又可细分为两种实现方

[转载]使用node.js+socket.io搭建实时消息系统

在开发web应用时,经常会有消息接收需求.例如后台处理完某个任务,需要告知用户等.一个简单的做法,是使用ajax轮询.这样带来的问题一是低效,二是消息触达不够实时.另一个方法是使用websocket来接收消息,但可惜IE不支持这种方式.下面推荐一种既能实时接收消息,又能兼容各种浏览器的方案,那就是node.js+socket.io. node.js的异步非阻塞模型,做消息推送非常合适.socket.io则负责屏蔽浏览器的差异,其会选择性的使用下列方式建立连接:websocket, flash s

使用Node.js+Socket.IO搭建WebSocket实时应用

Web领域的实时推送技术,也被称作Realtime技术.这种技术要达到的目的是让用户不需要刷新浏览器就可以获得实时更新.它有着广泛的应用场景,比如在线聊天室.在线客服系统.评论系统.WebIM等. 作者:潘良虎链接:https://www.zhihu.com/question/20215561/answer/26419995来源:知乎原文地址:http://www.plhwin.com/2014/05/28/nodejs-socketio/ WebSocket简介 谈到Web实时推送,就不得不说

Node.js与io.js那些事儿

14年12月,多位重量级Node.js开发者不满Joyent对Node.js的管理,自立门户创建了io.js.io.js的发展速度非常快,先是于2015年1月份发布了1.0版本,并且很快就达到了2.0版本,社区非常活跃.而最近io.js社区又宣布,这两个项目将合并到Node基金会下,并暂时由“Node.js和io.js核心技术团队联合监督”运营.本文将聊一聊Node.js项目的一些历史情况,与io.js项目之间的恩怨纠葛,他们将来的发展去向.希望能从历史的层面去了解这个开源项目在运营模式上是如何

Node.js与io.js的那些事儿

转自:http://www.infoq.com/cn/articles/node-js-and-io-js 去年12月,多位重量级Node.js开发者不满Joyent对Node.js的管理,自立门户创建了io.js.io.js的发展速度非常快,先是于2015年1月份发布了1.0版本,并且很快就达到了2.0版本,社区非常活跃.而最近io.js社区又宣布,这两个项目将合并到Node基金会下,并暂时由“Node.js和io.js核心技术团队联合监督”运营.本文将聊一聊Node.js项目的一些历史情况,