深入浅出node(3) 异步I/O
这篇主要整理深入浅出Node.js第三章 异步I/O
一) 异步I/O的原因 异步I/O主要有以下两点的需求
- 用户体验 同步的模式下,在浏览器中等待服务端数据的过程中,浏览器页面会锁死 同时请求A B 同步的情况下时间为 time(A) + time(B) 异步的情况下是 时间为 Max(time(A),time(B)) 并且当请求不断增长的时候,带来的差异更大
- 异步I/O能更好的分配资源 异步I/O不会阻塞后续的运算,将原有的等待I/O的时间分配给其余的任务去执行
二) 异步I/O实现现状
2.1 异步I/O与非阻塞I/O 对操作系统的内核来说只存在阻塞I/O和非阻塞I/O (我对书中这部分的理解是这样的 比如异步I/O是node为我们提供的一层API接口,让我们能通过非阻塞的形式去I/O)
操作系统对输入输出设备抽象成文件,内核在进行文件的I/O操作的时候,通过文件描述符进行管理,也就是应用程序需要I/O的时候,需要先打开文件描述符,在根据文件描述符去实现文件的读写 非阻塞I/O和阻塞I/O的区别主要在于阻塞I/O直接完成整个数据获取的流程,非阻塞I/O返回的是文件描述符,当需要获取数据的时候,在通过文件描述符去读取数据
2.2 轮询 轮询技术主要为了解决非阻塞I/O何时完成完整的I/O而出现的 下面是轮询技术的演变过程
- read 它通过重复检查I/O的状态来完成完整数据的读取 在得到数据前 CPU一直处于等待的状态

- select 它在read的基础上进行了一些改进,通过对文件描述符的事件状态进行判断来完成数据的I/O 它采用一个1024长度的数据来存储状态,所以它只能同时检测1024个文件描述符

- poll 它是在select基础上进行的改进,它采用链表的方式存储文件描述符,避免了数据的限制,但是在文件描述符很多的时候,性能有所下降

- epoll 该方案是Linux下最高的事件通知机制 当没有I/O事件的时候,它会休眠(观察者),充分的利用了事件通知,执行回调来代替遍历查询 不会浪费CPU 所以执行的效率更高

2.3 理想的非阻塞异步I/O 理想的应该是由应用程序发起异步方法,不需要遍历或者事件唤醒等方式轮询,直接进入下一个任务,在I/O完成后通过信号或者回调的方式将数据传送给应用程序

2.4 现实的异步I/O

三) Node中的异步I/O
3.1 事件循环 在进程启动的时候,Node会创建一个类似于while(true)的循环,每执行一次循环体称为Tick,每一次Tick的时候会查看是否有事件等待处理,如果有就取出事件并且执行相应的回调函数,没有的话就退出进程 事件循环是典型的生产者消费者模型 在Windows下这个循环基于IOCP,而在*nix基于多线程创建

3.2 理解异步回调的执行过程
3.2.1 基础
- 请求对象 从javascript发起调用到内核执行完I/O操作的过渡过程中的中间产物 所有的状态都保存在这个对象,包括送入线程池等待执行以及I/O操作完毕后的回调处理
- Node中的经典调用模式 javascript调用Node的核心模块,核心模块调用C++内建模块 内建模块通过libuv(跨平台)进行系统调用
3.2.2 过程
- 从javascript到内建模块的调用过程中会创建一个请求对象,将javascript层传入的参数和方法都封装到这个请求对象上,回调函数会被设置到这个请求对象的oncomplete_sym上 ,供后续的调用,然后将这个请求对象推入线程池中等待执行,此时javascript的调用立即返回(底层的I/O仍然可能是阻塞或者是非阻塞的)
- 线程池中的I/O执行完毕后,会将结果存储在请求对象的result上,此时它会通知本身的执行状态已经完毕,并且将线程归还给线程池
- 在每次的Tick中,检查是否有执行完的请求,如果有将请求对象加入I/O观察者的队列,并且当做事件进行处理
- I/O观察者会取出事件回调函数并且将result当做参数传递给回调函数执行,这样就达到了执行回调函数的目的

四)事件驱动与高性能服务器
几种经典的服务器模型
- 同步式 一次只能处理一个请求,并且其余的请求都处于等待的状态
- 每进程/每请求 为每个请求启动一个进程,但是不具备扩展性,因为系统的资源只有那么多
- 每线程/每请求 为每个请求启动一个线程来处理,但是线程占用一定的内存,大并发到来的时候,会造成系统运行缓慢
Node的高性能正是因为它的事件驱动模式.

深入浅出node(3) 异步I/O的更多相关文章
- 深入浅出node(4) 异步编程
一)函数式编程基础 二)异步编程的优势和难点 2.1 优势 2.2 难点 2.2.1 异常处理 2.2.2 函数嵌套过深 2.2.3 阻塞 2.2.4 多线程编程 2.2.5 异步转同步 三)异步编程 ...
- 《深入浅出Node.js》第4章 异步编程
@by Ruth92(转载请注明出处) 第4章 异步编程 Node 能够迅速成功并流行起来的原因: V8 和 异步 I/O 在性能上带来的提升: 前后端 JavaScript 编程风格一致 一.函数式 ...
- 《深入浅出Node.js》第3章 异步I/O
@by Ruth92(转载请注明出处) 第3章 异步I/O Node 的基调:异步 I/O.事件驱动.单线程. Node 不再是一个服务器,而是一个可以基于它构建各种高速.可伸缩网络应用的平台. No ...
- 深入浅出Node.js (3) - 异步I/O
3.1 为什么要异步I/O 3.1.1 用户体验 3.1.2 资源分配 3.2 异步I/O实现现状 3.2.1 异步I/O与非阻塞I/O 3.2.2 理想的非阻塞异步I/O 3.2.3 现实的异步I/ ...
- 深入浅出node(1) Node简介
这一系列主要是自己在学习深入浅出node.js这本书的学习笔试,部分加入了自己的一些理解 分享给一起学习node的小伙伴 自己还是个初学者 有很多地方理解的不到位 一起交流 一 什么是node 1.1 ...
- 深入浅出Node.js(一):什么是Node.js
Node.js从2009年诞生至今,已经发展了两年有余,其成长的速度有目共睹.从在github的访问量超过Rails,到去年底Node.jsS创始人Ryan Dalh加盟Joyent获得企业资助,再到 ...
- 一个月时间整理《深入浅出Node.js》
今天终于把朴灵老师写的<深入浅出Node.js>给学习完了, 这本书不是一本简单的Node入门书籍,它没有停留在Node介绍或者框架.库的使用层面上,而是从不同的视角来揭示Node自己内在 ...
- 转:Node.js异步处理CPU密集型任务的新思路
原文来自于:http://www.infoq.com/cn/articles/new-idea-of-nodejs-asynchronous-processing-tasks?utm_source=i ...
- 读书笔记: 深入浅出node.js
>> 深入浅出node.js node.js是c++编写的js运行环境 浏览器: 渲染引擎 + js引擎 后端的js运行环境 node.js用google v8引擎,同时提供很多系统级的A ...
随机推荐
- Java Math 取整的方式
1.Math.floor floor,英文原意:地板. Math.floor 函数是求一个浮点数的地板,就是 向下 求一个最接近它的整数,它的值肯定会小于或等于这个浮点数. 2.Math.ceil c ...
- web安全测试资料
最近因为工作需要,整理了安全测试工具AppScan的一个教程.目录如下: 网上对于appscan的资料挺多,但是也很乱很杂.不利于系统的学习,这也是我为什么整理这样一份指导手册. 在这份手册里,主要包 ...
- mfc的OnInitDialog的返回值
以前从未注意过初始化函数的返回值,今天看到书中所述,以后可能用得上. OnInitDialog的返回值告诉windows如何处置输入焦点,如果返回 TRUE,则windows将输入焦点指派给制表键控制 ...
- ArchLinux+Win10双系统的Grub配置
解决:ArchLinux+Win10双系统,Grub设置 原装的Win10,装完ArchLinux后,要进入Win10一段时间只能通过boot选择. Grub的菜单里并没有.Grub安装过程是参考wi ...
- 前端学PHP之面向对象系列第三篇——三大特性
× 目录 [1]封装 [2]继承[3]多态 前面的话 php面向对象编程的三大特性是封装性.继承性和多态性.本文将介绍php的这三大特性 封装 封装就是把对象中的成员属性和成员方法加上访问修饰符( p ...
- CSS3制作心形头像
1.功能需求: 最近有一个基于微信开发的Mobile Web项目,是一个活动页面.功能需求:用户使用微信扫描二维码,然后授权使用微信登录,然后读取用户的昵称和头像,然后显示在一个饼图上面.头像需要有一 ...
- 如何用C#代码判断一个类的类型
var s = ""; s.GetType().IsClass; 来自为知笔记(Wiz)
- IOS开发之显示微博表情
在上一篇博客中山寨了一下新浪微博,在之后的博客中会对上一篇代码进行优化和重用,上一篇的微博请求的文字中有一些表情没做处理,比如带有表情的文字是这样的“我要[大笑],[得意]”.显示的就是请求的字符串, ...
- ASP.NET MVC Ajax.ActionLink 简单用法
ASP.NET MVC 项目中,如何使用类似于 iframe 的效果呢?或者说 Ajax 局部刷新,比如下面操作: 我们想要的效果是,点击 About 链接,页面不刷新(地址栏不变),然后下面的内容进 ...
- android中ProgressBar和ListView
ProgressBar进度条的使用情况: 进度条的.xml声明:如果不声明格式,则默认格式为转圆圈的形式,声明进度条的visibility为不可见. <ProgressBar android:i ...