Node.JS中事件轮询(Event Loop)的解析


Posted in Javascript onFebruary 25, 2017

当我们知道I/O操作和创建新线程的开销是巨大的!

网站延迟的开销

对于一个网站,后台大多不需要进行复杂的计算,我们的程序大多时间花费在I/O读取上。

看到一个数据:IO操作可以比数据处理慢几个数量级。高端SSD固态硬盘的读取速度可以达到200mb-700mb/s;读取1000字节需要1.4微秒。而在此期间,2GHZ频率的CPU可以执行28000个指令处理周期。而网络数据的IO甚至更慢!

Node.JS中事件轮询(Event Loop)的解析

NodeJS采用单线程非阻塞的架构解决老大难的IO问题

当采用多线程时,为每一个请求开启一个新的线程(Apache就是这样做的)。当并发增多,线程的消耗会十分严重。

什么是阻塞和非阻塞呢?

阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。
非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。

var fs = require("fs");
fs.readFile("./testfile", "utf8", function(error, file) { 
  if (error) throw error; 
  console.log("我读完文件了!");
});
console.log("我不会被阻塞!");

用node执行以下代码,会先输出我不会被阻塞,再输出我读完文件了

一个知乎的回答:

你打电话问书店老板有没有《分布式系统》这本书,你如果是阻塞式调用,你会一直把自己“挂起”,直到得到这本书有没有的结果,如果是非阻塞式调用,你不管老板有没有告诉你,你自己先一边去玩了, 当然你也要偶尔过几分钟check一下老板有没有返回结果。

NodeJS的事件轮询

这是node虽然为单线程,但是可以处理大并发,高吞吐量的核心。一个事件轮询拥有下面三个组件

  1. 事件队列:这是一个FIFO模型的队列,一方推入事件,另一方推出事件
  2. 队列的读取轮询线程组件,也就是主角Event Loop,
  3. 单独的线程池,用来执行长任务(也就是threadpool,node底层,用C++写的,不会阻塞)

Node.JS中事件轮询(Event Loop)的解析

在nodejs中,只有一个主线程(也就是前面说的单线程)来不断读取轮询(书中称为调用I/O观察者)队列中是否有事件。

而对于读取文件,HTTP

请求等(现代cpu处理能力很强,事件处理相当快,导致运行速度下降的瓶颈在I/O)比较容易堵塞的事件,就在这个单线程中

执行肯定会造成堵塞,所以Event Loop

会把这类型的事件交给底层的线程池执行,并给予线程池一个回调函数,当线程池操作

完成这堵塞任务后,便把结果和回调函数一起再放入轮询队列中。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
JavaScript类和继承 this属性使用说明
Sep 03 Javascript
javascript异步编程的4种方法
Feb 19 Javascript
JavaScript中使用Math.PI圆周率属性的方法
Jun 14 Javascript
巧方法 JavaScript获取超链接的绝对URL地址
Jun 14 Javascript
BootStrap Progressbar 实现大文件上传的进度条的实例代码
Jun 27 Javascript
JS中的phototype详解
Feb 04 Javascript
Bootstrap 过渡效果Transition 模态框(Modal)
Mar 17 Javascript
vue.js删除动态绑定的radio的指定项
Jun 02 Javascript
laydate 显示结束时间不小于开始时间的实例
Aug 11 Javascript
详解.vue文件解析的实现
Jun 11 Javascript
vue.js项目 el-input 组件 监听回车键实现搜索功能示例
Aug 25 Javascript
vue控制多行文字展开收起的实现示例
Oct 11 Javascript
走进javascript——不起眼的基础,值和分号
Feb 24 #Javascript
angular.js 路由及页面传参示例
Feb 24 #Javascript
实例解析js中try、catch、finally的执行规则
Feb 24 #Javascript
js中开关变量使用实例
Feb 24 #Javascript
angularjs点击图片放大实现上传图片预览
Feb 24 #Javascript
js实现导航吸顶效果
Feb 24 #Javascript
canvas绘制多边形
Feb 24 #Javascript
You might like
提问的智慧
2006/10/09 PHP
php运行出现Call to undefined function curl_init()的解决方法
2010/11/02 PHP
php中根据某年第几天计算出日期年月日的代码
2011/02/24 PHP
解析PHP函数array_flip()在重复数组元素删除中的作用
2013/06/27 PHP
ThinkPHP CURD方法之limit方法详解
2014/06/18 PHP
Yii 框架控制器创建使用及控制器响应操作示例
2019/10/14 PHP
JQuery下关于$.Ready()的分析
2009/12/13 Javascript
jquery 操作表格实现代码(多种操作打包)
2011/03/20 Javascript
正则表达式搭配js轻松处理json文本方便而老古
2013/02/17 Javascript
display和visibility的区别示例介绍
2014/02/26 Javascript
jQuery实现连续动画效果实例分析
2015/10/09 Javascript
浅析JS动态创建元素【两种方法】
2016/04/20 Javascript
TypeScript入门-基本数据类型
2017/03/28 Javascript
Webpack常见静态资源处理-模块加载器(Loaders)+ExtractTextPlugin插件
2017/06/29 Javascript
AngularJS实现的获取焦点及失去焦点时的表单验证功能示例
2017/10/25 Javascript
Vue项目全局配置页面缓存之按需读取缓存的实现详解
2018/08/01 Javascript
vue获取元素宽、高、距离左边距离,右,上距离等还有XY坐标轴的方法
2018/09/05 Javascript
jQuery实现鼠标移入移出事件切换功能示例
2018/09/06 jQuery
微信小程序实现slideUp、slideDown滑动效果及点击空白隐藏功能示例
2018/12/11 Javascript
微信小程序自定义可滑动日历界面
2018/12/28 Javascript
Python实现list反转实例汇总
2014/11/11 Python
Python中exit、return、sys.exit()等使用实例和区别
2015/05/28 Python
Python实现二维数组按照某行或列排序的方法【numpy lexsort】
2017/09/22 Python
python二维码操作:对QRCode和MyQR入门详解
2019/06/24 Python
opencv resize图片为正方形尺寸的实现方法
2019/12/26 Python
python中的对数log函数表示及用法
2020/12/09 Python
pycharm 使用anaconda为默认环境的操作
2021/02/05 Python
英国曼彻斯特宠物用品品牌:Bunty Pet Products
2019/07/27 全球购物
MATCHESFASHION澳大利亚/亚太地区:英国时尚奢侈品电商
2020/01/14 全球购物
通信生自我鉴定
2014/01/18 职场文书
小学语文教学反思
2014/02/10 职场文书
弄虚作假心得体会
2014/09/10 职场文书
通知函格式范文
2015/04/27 职场文书
《检阅》教学反思
2016/02/22 职场文书
Python爬虫实战之爬取携程评论
2021/06/02 Python
Pycharm远程调试和MySQL数据库授权问题
2022/03/18 MySQL