nodejs的核心之一就是非阻塞的异步IO,于是想知道它是怎么实现的,挖了下nodejs源码,找到些答案,在此跟大家分享下。首先,我用了一段js代码test-fs-read.js做测试,代码如下:
var path = require('path'),
fs = require('fs'),
filepath = path.join(__dirname, 'experiment.log'),
fd = fs.openSync(filepath, 'r');
fs.read(fd, 12*1024*1024, 0, 'utf-8', function(err, str, bytesRead) {
console.log('[main thread] execute read callback');
});
console.log('[main thread] execute operation after read');
这段代码的异步IO操作就在fs.read的调用上,读取的experiment.log是一个12M的文本文件,所谓的异步,大家大概能想得到运行时会先打印
[main thread] execute operation after read
然后打印回调函数中的
[main thread] execute read callback
但大家也许还听说过,nodejs是单线程的,那又是怎么实现异步IO的呢?读文件操作是在哪里执行的呢?读完又是怎么调用回调函数的呢?猜想读文件可能是在另一个线程中完成的,读完后通过事件通知nodejs执行回调。为了一探究竟,debug了一把nodejs和libeio源码,重新编译后,运行测试代码node test-fs-read.js,输出如下:
可以看到,nodejs的IO操作是通过调用libeio库完成的,debug从fs.read开始,js代码经过v8编译后,fs.read会调用node_file.cc中的Read方法,测试代码的运行经历了以下步骤:
1 node_file.cc中的Read方法调用libeio(eio.c)的eio_read, read请求被放入请求队列req_queue中。
2 主线程创建了1个eio线程,此时主线程的read调用返回。
3 eio线程从req_queue中取出1个请求,开始执行read IO
4 主线程继续执行read调用后的其它操作。
5 主线程poll eio,从响应队列res_queue取已经完成的请求,此时res_queue为空,主线程stop poll
6 eio线程完成了read IO,read请求被放入响应队列res_queue中,并且向主线程发送libev事件want_poll(通过主线程初始化eio时提供的回调函数)。
7 eio线程从req_queue中取下一个请求,此时已经没有请求。
8 主线程响应want_poll事件,从res_queue中取出1个请求,取出请求后res_queue变为空,主线程发送done_poll事件。
9 主线程执行请求的callback函数。
还需要说明的是,当同时有多个IO请求时,主线程会创建多个eio线程,以提高IO请求的处理速度。
为了更清晰的看到nodejs的IO执行过程,图示如下,序号仅用来标示流程,与上述步骤序号并无对应关系。
最后总结几条,不当之处还请大家指正。
1 nodejs通过libev事件得到IO执行状态,而不是轮询,提高了CPU利用率。
2 虽然nodejs是单线程的,但它的IO操作是多线程的,多个IO请求会创建多个libeio线程(最多4个),使通常情况的IO操作性能得到提高。
3 但是当IO操作情况比较复杂的时候,有可能造成线程竞争状态,导致IO性能降低;而且libeio最多创建4个线程,当同时有大量IO请求时,实际性能有待测量。另外,由于每个IO请求对应一个libeio的数据结构,当同时有大量IO操作驻留在系统中时候,会增加内存开销。
4 Libeio为了实现异步IO功能,带来了额外的管理,当IO数据量比较小的时候,整体性能不一定比同步IO好。
相关推荐
开发语言:nodejs 框架:Express 数据库:mysql 5.7(一定要5.7版本) 数据库工具:Navicat11 开发软件:VS code/HBuilder X 浏览器:谷歌浏览器 node配置环境链接:链接:...
开发语言:nodejs 框架:Express 数据库:mysql 5.7(一定要5.7版本) 数据库工具:Navicat11 开发软件:VS code/HBuilder X 浏览器:谷歌浏览器 node配置环境链接:链接:...
开发语言:nodejs 框架:Express 数据库:mysql 5.7(一定要5.7版本) 数据库工具:Navicat11 开发软件:VS code/HBuilder X 浏览器:谷歌浏览器 node配置环境链接:链接:...
开发语言:nodejs 框架:Express 数据库:mysql 5.7(一定要5.7版本) 数据库工具:Navicat11 开发软件:VS code/HBuilder X 浏览器:谷歌浏览器 node配置环境链接:链接:...
开发语言:nodejs 框架:Express 数据库:mysql 5.7(一定要5.7版本) 数据库工具:Navicat11 开发软件:VS code/HBuilder X 浏览器:谷歌浏览器 node配置环境链接:链接:...
开发语言:nodejs 框架:Express 数据库:mysql 5.7(一定要5.7版本) 数据库工具:Navicat11 开发软件:VS code/HBuilder X 浏览器:谷歌浏览器 node配置环境链接:链接:...
开发语言:nodejs 框架:Express 数据库:mysql 5.7(一定要5.7版本) 数据库工具:Navicat11 开发软件:VS code/HBuilder X 浏览器:谷歌浏览器 node配置环境链接:链接:...
访问Node.js官方网站([https://nodejs.org/en/download/](https://nodejs.org/en/download/) 或 [https://nodejs.org/zh-cn/download/](https://nodejs.org/zh-cn/download/))以获取最新版本的二进制安装包。...
rreact:https://react.nodejs.cn/reference/react/hooks vant:https://vant-contrib.gitee.io/vant/#/zh-CN axios:https://www.axios-http.cn/docs/api_intro vite:https://vitejs.cn/ redux:...
本篇文章将深入探讨Node.js如何实现异步I/O,以及相关源码和工具的应用。 一、异步I/O基础 异步I/O是一种编程模式,它使得程序在等待I/O操作完成时不会阻塞,可以继续执行其他任务。在Node.js中,这一特性主要通过...
[nodejs搭建,express框架,nodejs简单页面抓取,JS正则,canvas光晕效果] 在线:http://wangxinsheng.herokuapp.com/weather [heroku服务器访问国内好像很慢。。。所以抓取页面也特别慢] nodejs抓取页面,js正则提取数据
国内目前关注最高,维护最好的一个关于nodejs的网站应该是http://www.cnodejs.org/ windows系统下简单nodejs环境配置。 第一步:下载安装文件 下载地址:官网https://nodejs.org/en/download/ 这里用的是 第二步...
个demo是国内牛人赵书剑开发的视频聊天室,基于webrtc.io实现。 该项目源码和文档下载地址是http://ishare.iask.sina.com.cn/f/35083616.html,源码在https://github.com/zsj2145676。 经修改后在本人公司局域网...
1.此电脑--属性--高级--环境变量 用户变量:新建变量NVM_HOME 值:D:\nvm ; 新建变量NVM_SYMLINK 值:D:\nvm\nodejs 系统变量:新建变量NVM_HOME 值:D:\nvm ; 新建变量NVM_SYMLINK 值:D:\nvm\nodejs 2.找到nvm...
SHA: 3b65d29024b9decdbb1148b12fe87bcb7f3a6a56ff38475f5dc9dd1cfc7fd6b2 官网: http://ghidra-sre.org/ (需要翻) 其它网友脱下来的安装说明 英文: https://blog.csdn.net/wxh0000mm/article/details/88288480 ...
1. **下载安装包**:访问 https://nodejs.org/en/download/ 或者通过提供的本地资源 `node-v18.12.1-x86.msi` 下载适用于 x86 架构的安装文件。 2. **运行安装程序**:双击下载的 `.msi` 文件,启动安装向导。 3. **...
蚁群 介绍 AntColony(Github)是findit磁力搜索引擎的核心。在DHT网络中,收集活跃资源的infohash,下载并解析资源的种子文件,存入数据库等。AntColony是某些功能的合集,也可以单独运行其中的部分功能,所以...
进入安装目录: cd /opt ...重命名安装包:mv node-v12.14.0-linux-x64 nodejs 添加NODE_PATH环境变量 <>vim /etc/profile <>在文件末尾添加如下内容 export NODE_HOME=/opt/nodejs export PATH=PATH:PATH:PATH:N
Nodejs下载:https://nodejs.org/download/release/v16.19.0/ VUE CLI:2.7.13,详情可查看package.json文件 API地址修改文件:src/request/index.js 路由修改文件:src/router/config.js 注意事项:由于插件包太大,...