【译】node js event loop part 1.1

原文node

先说1.1总揽:react

  • Reactor模式
  • Reactor模式中的协调机制Event Loop
  • Reactor模式中的事件分离器Event Demultiplexer
  • 一些Event Demultiplexer处理不了的复杂I/O接口好比File I/O、DNS等
  • 复杂I/O的解决方案
  • 未完待续

前言

nodejs和其余编程平台的区别在于如何去处理I/O接口,咱们听一我的介绍nodejs,老是会说是一个基于v8引擎,没有堵塞,事件驱动的语言,那这些又意味着什么呢?什么叫‘没有堵塞’和‘事件驱动’?全部的答案都在nodejs的核心——Event Loop
在这一系列的帖子中,咱们将一块儿去描述什么是Event Loop,它是如何工做的,它是如何影响咱们的应用的,如何充分的利用他甚至更多。为何不用一篇代替一个系列的帖子呢,由于这样的话,他就会变成一个很长很长的帖子,我会确定会错过不少东西,所以我才把它写成一个系列,在第一篇帖子中,我将讲述nodejs如何工做,如何经过I/O,他如何与其余平台一块儿工做等。linux

Reactor Pattern

nodejs工做在一个事件驱动的模型中,这个模型涉及一个事件分离器和事件循环,全部的I/O请求最终将会生成一个事件完成、事件失败或者唤醒其余事件的结果。这些事件将会根据如下规则作处理:编程

  • 1.事件分离器收到I/O请求,以后将这些请求委托给相应的硬件
  • 2.曾经被处理过的请求(好比来自可读取文件的数据,来自可读取接口的数据),事件分离器会为要进行的特殊操做添加注册回调程序。
  • 3.若是事件能够在事件循环中被处理,那么将有序的被执行,直到循环为空
  • 4.若是没有事件在事件循环中,或者事件分离器没有添加任何请求,这个 程序将被完成,不然,程序将从第一步在开始,进行循环操做。

这整个工程的协调机制咱们叫作Event Loop设计模式

Event Loop

Event Loop实际上是一个单线程的半无限循环,为何会说是半无限呢?由于在没有工做须要完成的时候程序会退出。从开发者的角度来讲,这些是程序退出的点。网络

注意:不要把Event Loop和Event Emitter弄混淆,Event Emitter和这个机制彻底是不一样的概念,在最后一篇帖子,我会解释Event Emitter是如何经过Event Loop影响事件的处理。

上面的图是对NodeJs如何工做以及展现一种被叫作Reactor Pattern的主要组件的设计模式的高级概览。
可是真正的复杂度远超于它,那它有多复杂呢?异步

Event demultiplexer不是一个在全部os平台中解析全部I/O类型的单一组件。
Event queue在这里展现出来的不是一个单一的队列,在其中全部类型的事件会在队列中排队或者从队列中移除,而且I/O不是惟一一个要排队的事件类型

让咱们继续深挖async

Event Demultiplexer

Event Demultiplexer并非一个现实存在的组件,而是在reactor pattern中的一个抽象概念。ide

在现实中,Event Demultiplexer 在不一样的系统中以不一样的名字被实现,好比在linux中叫作epoll, 在MacOS中叫作kqueue,在Solaris中叫event post,在window系统下叫作IOCP等。函数

nodeJS可使用Event Demultiplexer提供的底层非阻塞、异步硬件I/O功能。

Complexities in File I/O

可是使人苦恼的是,不是全部类型的I/O均可以使用Event Demultiplexer被执行,甚至是在相同的操做系统中,支持不一样类型的I/O也是很复杂的。

一般来讲,epoll, kqueue, event ports和IOCP可使用非阻塞的方式执行网络I/O。

可是文件I/O就复杂多了,某些系统,好比Linux不支持彻底异步的方式去访问文件系统,在MacOS系统中文件系统对事件的发送和接收会有限制(你能够在这里了解更多)。

为了提供彻底异步而去解决全部文件系统的复杂性是很是复杂的,几乎是不可能的。

Complexities in DNS

和文件I/O同样,由node API提供某些DNS的功能也存在必定的复杂性。

好比dns.lookup等Node DNS功能访问系统的一些配置文件,例如nsswitch.conf、resolv.conf和/etc/hosts。

上面描述的文件系统复杂性也适用于dns.resolve函数。

The solution?

所以,引入了一个线程池来支持I/O功能,这些功能不能由硬件异步I/O实用程序(如epoll / kqueue / event ports或IOCP)直接解决。

如今咱们知道不是全部的I/O功能均可以在线程池中运行。nodeJS已经尽最大努力来使用非阻塞和硬件的异步I/O方式来完成大部分I/O功能,可是对于一些复杂的、阻塞的I/O仍是经过引入一个线程池的方式来解决

未完待续

该篇先翻译到这,有些地方翻译的很差请指出,过几天我会继续出第二篇。

相关文章
相关标签/搜索