理解异步IO模型

来源:互联网 发布:linux 退出vi 命令 编辑:程序博客网 时间:2024/05/16 05:49
Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient

事件驱动

—监听事件的状态来做出相应的行为

Event-driven programing 是一种由事件/动作的触发来决定程序的执行流程的 模式。

在Node.js中,不同于新开一个线程来处理请求的线程驱动,Node.js是事件驱动,通过Event Loop循环,采用回调的方法取出Event Queue中的消息进行处理。当事件状态发生变化的时候,将消息压入Event Queue。

I/O 操作

传统的I/O操作像一个本地函数的调用,在函数执行完毕之前,进程被阻塞。也就是说一个进程只可以在同一时刻只能做一件事情。这导致了我们必须使用多进程,而多进程会导致耗费大量的内存,上下文的切换也将会消耗大量资源,拖慢执行速度。

阻塞/非阻塞的区分依据:在等待消息返回时进程/线程的状态,数据报是否准备就绪?进程/线程是否被挂起?同步/异步的区分依据:消息发出后是否立刻返回?是否导致请求进程阻塞?

Linux中的5种I/O模型

将I/O操作的流程分为两个阶段:

1.等待数据报准备好。

2.将数据从内核拷贝到数据空间。

前四种情况都是同步I/O,他们的第二阶段(拷贝数据报的阶段)都是阻塞的。


阻塞式I/O模型

在阻塞式I/O模型当中,等待数据报阶段是阻塞的。


非阻塞式I/O模型

在非阻塞I/O模型中,等待数据报准备阶段,发起读写操作之后,立即返回函数,通过轮询去查询数据报是否准备好,在等待阶段不阻塞。


I/O多路复用模型

在等待数据报准备阶段,系统调用不阻塞,但是select、poll、epoll这样的系统调用是会阻塞的。
该方法的优势在于单个进程同时处理多个IO,不断轮询,当有监测到的数据报到达时,通知用户进程。

select函数通过一个阻塞函数来监听多个文件描述符,监测到有一个准备好时立刻返回函数。select的平台支持性良好,但是单个进程一般只能监测1024个文件描述符,(可以通过编译内核、修改宏定义来提升限制)。

poll函数监测到事件之后,返回要发生的事件,没有最大数量限制,但是select与poll都需要遍历文件描述符来获取就绪的socket,过量的描述符会导致效率下降。

epoll函数没有描述符限制,且使用一个文件描述符管理多个描述符,将文件描述符的事件存放到事件表中,更加的灵活高效。


信号驱动I/O模型

调用 sigaction 等系统调用安装信号处理函数,在内核确认数据可读之后,便会给相应的线程发送通知。


异步I/O模型

调用某个API,比如Linux中的AIO。在两个阶段都执行完毕之后才返回通知。


I/O分类比较

一般来说,没有异步阻塞,因为没有实际意义。

Node.js中的事件驱动&异步I/O模型

Node.js驱动模型

原创粉丝点击