网络IO模型

本文详细介绍了IO模型的五种类型:同步阻塞IO、同步非阻塞IO、同步阻塞多路IO复用(Reactor模式)、同步非阻塞信号驱动IO和异步非阻塞IO(Proactor模式)。讨论了它们的工作原理、优缺点,并以伪代码形式展示了各模型的执行流程,揭示了不同IO模型在处理并发和效率方面的差异。
摘要由CSDN通过智能技术生成

IO分类

同步和异步

同步和异步的描述的是用户线程与内核的数据交互方式

同步是指用户线程从socket中读到的数据,一定和内核中socket读到的数据是一致的

异步是指用户线程从socket中读到的数据,和内核中socket读到的数据不一定一致

阻塞和非阻塞

阻塞和非阻塞的概念描述的是调用内核IO操作的方式

非阻塞是指用户线程关于该socket能立刻得到内核的IO操作结果不会导致wait状态

阻塞是指用户线程关于该socket不能立刻得到内核的IO操作结果处于wait状态
IO分类
服务器端编程经常需要构造高性能的IO模型,常见的IO模型有四种:

  1. 同步阻塞IO(Blocking IO):即传统的IO模型
  2. 同步非阻塞IO(Non-blocking IO):默认创建的socket都是阻塞的,非阻塞IO要求socket被设置为NONBLOCK。注意这里所说的NIO并非Java的NIO(New IO)库
  3. 同步阻塞多路IO复用(IO Multiplexing):即经典的Reactor设计模式,也称为同步阻塞复用IO,Java中的Selector、poll和Linux中的epoll都是这种模型
  4. 同步非阻塞信号驱动IO
  5. 异步非阻塞IO(Asynchronous IO):即经典的Proactor设计模式

同步阻塞IO (BIO Blocking IO)

BIO
用户线程通过系统调用read发起IO读操作,内核等到数据包到达内核空间后,然后将接收的数据拷贝到用户空间,完成read操作
read过程

用户线程使用同步阻塞IO模型的伪代码描述为:
{
	read(socket, buffer);
  	process(buffer); 
}

即用户需要等待read将socket中的数据读取到buffer后,才继续处理接收的数据。整个IO请求的过程中,用户线程是被阻塞的,这导致用户在发起IO请求时,不能做任何事情,对CPU的资源利用率不够

同步非阻塞式IO(NIO Non-Blocking IO)

NIO

  • 同步非阻塞IO是在同步阻塞IO的基础上,将socket设置为NONBLOCK。这样做用户线程可以在发起IO请求后可以立即返回
  • 由于socket是非阻塞的方式,因此用户线程发起IO请求时立即返回。但并未读取到任何数据,用户线程需要不断地发起IO请求,直到数据到达后,才真正读取到数据
 用户线程使用同步非阻塞IO模型的伪代码描述为:
 {
 	while(read(socket, buffer) != SUCCESS){
	//添加一些操作
	}
	process(buffer);
}
  • 整个IO请求的过程中,虽然用户线程每次发起IO请求后可以立即返回,但是为了等到数据,仍需要不断地轮询、重复请求,消耗了大量的CPU的资源。一般很少直接使用这种模型,而是在其他IO模型中使用非阻塞IO这一特性

同步阻塞多路IO复用

多路IO复用模型

  • 多路IO复用模型是建立在内核提供的多路分离函数select、poll基础之上的,使用select、poll函数可以避免同步非阻塞IO模型中重复轮询的问题
  • 多路IO 复用(IO multiplexing),也称事件驱动 IO(event-driven IO),就是在单个内核线程里同时监控多个套接字socket ,通过 select 或poll 轮询所负责的所有 socket,当某个socket 有数据到达了,就通知用户进程
  • IO 复用同非阻塞 IO 本质一样(都轮询所负责的所有 socket),不过利用了新的 select 系统调用,由内核来负责本来是请求进程该做的轮询操作。看似比非阻塞 IO 还多了一个系统调用开销,不过因为可以支持多路 IO,才算提高了效率
  • 阻塞体现在用户线程首先将需要进行IO操作的socket添加到select中,然后阻塞等待内核告知select系统调用返回(select 或poll 轮询所负责的所有 socket,需要等待select 或poll的返回,详情参考fd集合
  • 有数据到达的socket被激活,select函数返回。内核让之前监听该socket的用户线程正式发起read请求,读取数据并执行。其它没有数据到达的socket对应的监听用户线程处于阻塞状等待内核通知
  • NIO非阻塞体现在内核线程调用select监听多个Socket,内核线程的状态是非阻塞的

Reactor设计模式

Reactor设计模式

< < use > > 表示调用
图中除绿色外每一个方框代表一个对象,对象中包含多个方法

同步非阻塞信号驱动IO

信号驱动IO

  • 同步非阻塞信号驱动IO 与 NIO 最大的区别就在于,在 /IO 执行的数据准备阶段,不需要轮询
  • 当用户进程需要等待数据的时候,会向内核发送一个信号,告诉内核我要什么数据,然后用户进程就继续做别的事情去了,而当内核中的数据准备好之后,内核立马发给用户进程一个信号,说”数据准备好了,快来查收“,用户进程收到信号之后,立马调用 recvfrom,去查收数据

异步非阻塞IO

异步非阻塞IO

  • 异步 IO 真正实现了 IO 全流程的非阻塞。用户进程发出系统调用后立即返回,内核等待数据准备完成,然后将数据拷贝到用户进程缓冲区,然后发送信号告诉用户进程 IO 操作执行完毕
  • 与前面同步的IO相比,异步IO不再需要等待数据拷贝,因为数据已经放入了用户进程缓冲区,而同步IO在内核数据拷贝阶段均会阻塞
  • 目前仅有 windows 的 IOCP 模型支持异步IO

Proactor设计模式

Proactor设计模式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值