-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
异步存在于各个编程语言中,包括nodejs,甚至nodejs将异步发挥地更加炉火纯青,而libuv则承担了nodejs异步模型的主要工作,本文将对nodejs的异步进行简要分析,
异步API
nodejs中的异步API分为I/O异步和非I/O异步
-
I/O 异步:
- 网络I/O
- 文件I/O
-
非I/O异步
- setTimeout、setInterval
- setImmediate
- process.nextTick
- promise
I/O 异步
一、 网络I/O
libuv为了实现高效网络I/O,底层封装了各个平台的高效I/O模型。
- windows: IOCP完成端口
- sunos:events port
- OSX和一些BSD系统上:kquene
- linux系统:epoll
简单来说,nodejs 将网络 I/O 任务通过 libuv 传递给操作系统去处理,操作系统监听网络事件,一旦有了结果,就返回libuv的工作原理大致如下:
- 1、nodejs 接收到网络I/O任务,绑定事件。
- 2、libuv 将网络I/O下发给操作系统,绑定事件。
- 3、操作系统监听网络 I/O 事件,当有结果返回时,操作系统内核触发事件,并通知给 libuv。
- 4、libuv 监听到事件通知,在event-loop中执行该事件的回调函数。
至此,一个异步网络 I/O 任务就结束了,由于利用了各个平台上最优的 I/O 机制,所以nodejs的异步网络I/O很高效。
二、 文件 I/O
libuv在nodejs初始化的时候,还会开启一个默认4个线程的线程池,执行一些文件的I/O操作,以及一些DNS操作。我们之所以能够实现文件I/O的异步,就是利用了这个线程池。当有一个文件I/O任务到来时,nodejs将该任务放到一个队列中,等待空闲线程的到来。一旦有了空闲线程,就从队列中取出任务执行,执行完一个任务,该线程便返还到线程池中,等候下一个任务的到来。
当然,如果觉得4个线程不够用的话,可以在nodejs启动时设置环境变量* UV_THREADPOOL_SIZE*来指定线程池的大小,为了系统性能考虑,最大只能设置128个线程数。
结语
以上就是nodejs中 网络I/O和文件I/O的工作原理,当然很多细节没有涉及,如果感兴趣的话,大家可以研究下源码。
Metadata
Metadata
Assignees
Labels
No labels