NIO及Reactor编程模型就应该这么理解

1、Linux 网络 I/O模型

进程是无法直接操作I/O设备的,其必须通过系统调用请求内核来协助完成I/O动作,而内核会为每个I/O设备维护一个buffer。           如下图所示:

整个请求过程为: 用户进程发起请求,内核接受到请求后,从I/O设备中获取数据到buffer中,再将buffer中的数据copy到用户进程的地址空间,该用户进程获取到数据后再响应客户端。

在整个请求过程中,数据输入至buffer需要时间,而从buffer复制数据至进程也需要时间。因此根据在这两段时间内等待方式的不同,I/O动作可以分为以下五种模式:

阻塞I/O (Blocking I/O)

非阻塞I/O (Non-Blocking I/O)

I/O多路复用(I/O Multiplexing)

信号驱动I/O (Signal Driven I/O)

异步I/O (Asynchrnous I/O)

 

NIO就包含非阻塞I/O (Non-Blocking I/O) I/O多路复用(I/O Multiplexing)

下面我们逐个分析。

 

2、阻塞I/O (Blocking I/O)

在linux中,默认情况下所有的socket都是blocking,一个典型的读操作流程是这样:

1、用户进程掉用recvfrom,内核就开始了IO的第一个阶段:等待数据准备(wait for data)

2、这个时候内核就要等待足够的数据到来,等待完整的数据报包。

3、用户进程这边整个进程被阻塞。

4、当内核一直等到数据准备好了,开始第二阶段:从内核拷贝数据到用户内存;它就会将数据从内核中拷贝到用户内存,然后内核返回结果,用户进程才解除block的状态,重新运行起来。 blocking IO的特点就是在IO执行的两阶段被block了 

 

3、非阻塞I/O (Non-Blocking I/O)

在linux中,可以通过设置socket使其变为non-blocking。当对一个non-blocking socket执行读操作时,流程是这个样子:

1、当用户进程调用recvfrom时,系统不会阻塞用户进程,而是立刻返回一个ewouldblock错误,从用户进程角度讲 ,并不需要等待,而是马上就得到了一个结果。

2、用户进程判断标志是ewouldblock时,就知道数据还没准备好,于是它就可以去做其他的事,再次发送recvfrom。

3、一旦内核中的数据准备好了。并且又再次收到了用户进程的system call,那么它马上就将数据拷贝到了用户内存,然后返回。

 

4、I/O复用(I/O Multiplexing)

IO multiplexing这个词可能有点陌生,但是如果说select,epoll,大概就都能明白了。 select/epoll的好处就在于单个process就可以同时处理多个网络连接的IO。 它的基本原理就是select/epoll这个function会不断的轮询所负责的所有socket,当某个socket有数据到达了,就通知用户进程。     

我们来了解一下文件描述符fd :

1、Linux的内核将所有外部设备都可以看做一个文件来操作。那么我们对与外部设备的操作都可以看做对文件进行操作。

2、我们对一个文件的读写,都通过调用内核提供的系统调用;内核给我们返回一个filede scriptor(fd,文件描述符)。而对一个socket的读写也会有相应的描述符,称为socketfd(socket描述符)。

3、描述符就是一个数字,指向内核中一个结构体(文件路径,数据区,等一些属性)。

4、那么我们的应用程序对文件的读写就通过对描述符的读写完成。

5、一个socket描述符看作一个I/O.

可以把文件描述符理解为收发快递的快递格子,如下图:

1、将I/O操作比作收发快递。

2、收发快递都是通过快递格子完成,那么16个快递格 子,就可以进行16个I/O操作了。

3、select、epoll 相当于快递柜,管理快递格子

I/O服用流程如下图:

当用户进程调用了select,那么整个进程会被block,而同时,内核会“监视”所有select负责的socket,当任何一个socket中的数据准备好了,select就会返回。这个时候用户进程再调用read操作,将数据从内核拷贝到用户进程。

在IO multiplexing Model中,实际中,对于每一个socket,一般都设置成为non-blocking,但是,如上图所示,整个用户的process其实是一直被block的。只不过process是被select这个函数block,而不是被socket IO给block。

如果处理的连接数不是很高的话,使用select/epoll的web server不一定比使用multi-threading + blocking IO的web server性能更好,可能延迟还更大。select/epoll的优势并不是对于单个连接能处理得更快,而是在于能处理更多的连接。 

I/O复用模型select,poll,epoll:

 

select

poll

epoll

概述

客户端连接的文件描述符也就是socket,都被放到了一个集合中,调用select函数之后会一直监视这些socket中有哪些就绪

跟select类似,只是将socket放在链表里

select和poll的增强版本,基于内核的反射机制,主动告知描述符是否就绪。

数量限制

32位默认1024;64位默认2048

实现原理

遍历

遍历

水平触发和边缘触发

特点

有界循环

无界循环

1、无最大并发连接限制

2、效率提升,不是轮询方式

3、内存拷贝,利用mmap减少复制开销

 

5、NIO之Reactor编程模型

基于同步I/O的设计模式

1、事件驱动(event handling)

2、可以处理一个或多个输入源(one or more inputs)

3、通过Service Handler同步的将输入事件(Event)采用多路复用分发给相应的Request Handler(多个)处理

为什么要Reactor  每个模块的工作更加专一,耦合度更低,性能和稳定性也大量的提升,支持的可并发客户端数量可达到上百万级别. 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值