IO模型详解(5种IO模型图解)

IO模型详解(5种IO模型图解)-mikechen

IO模型是面试经常被问到的内容,下面我就重点详解5种常见的IO模型@mikechen

阻塞I/O模型

在阻塞I/O模型中,当程序发起一个I/O操作,例如:读取文件或从网络套接字接收数据,程序会被阻塞,直到操作完成。

这意味着程序必须等待,直到数据可用或写入完成,然后才能继续执行其他操作。

如下图示:

IO模型详解(5种IO模型图解)-mikechen

塞I/O的缺点:

  • 性能问题:在高并发的情况下,阻塞I/O可能会导致性能问题,因为一个被阻塞的I/O操作会阻止其他操作的执行,从而降低了应用程序的响应性和吞吐量。
  • 资源浪费:由于阻塞I/O会导致线程等待,因此可能需要创建大量线程来处理并发的I/O操作。每个线程都需要一些系统资源,这可能导致资源浪费。
  • 难以处理超时:阻塞I/O操作通常不容易设置超时,如果I/O操作长时间未完成,可能会导致应用程序陷入不可用状态。

适用场景:

阻塞I/O适用于以下情况:

  • 低负载和低并发的应用程序,性能要求不高。
  • 对于一些简单的命令行工具或脚本,阻塞I/O可能是一个方便的选择。
  • 当开发人员更关注代码的简洁性和易读性而不是最大吞吐量时。

 

非阻塞I/O模型

在非阻塞I/O模型中,当程序执行一个I/O操作时,它会立即返回而不会等待操作完成。

程序可以继续执行其他任务,而不会被I/O操作阻塞。

程序需要定期查询或轮询I/O操作的状态,以确定它们是否已经完成。

如下图所示:

IO模型详解(5种IO模型图解)-mikechen

非阻塞I/O的优点:

非阻塞I/O允许程序在执行I/O操作时继续响应其他请求,从而提高了应用程序的响应性。

 

非阻塞I/O的缺点:

  • 编程复杂性:实现非阻塞I/O通常需要更复杂的编程模式,因为程序需要定期查询I/O操作的状态并处理未完成的操作。
  • CPU消耗:轮询I/O状态会导致CPU消耗,因此需要小心设计以避免过多的轮询操作。

 

适用于高并发:

非阻塞I/O模型通常适用于需要处理大量并发连接或请求的应用程序,因为它允许应用程序在不增加大量线程的情况下处理并发I/O操作。

 

多路复用I/O模型

多路复用I/O模型允许程序同时监视多个I/O操作,而不需要主动轮询它们。

通常使用操作系统提供的机制,如selectpollepoll来等待多个I/O事件。

如下图所示:

IO模型详解(5种IO模型图解)-mikechen

多路复用I/O的优点:

  • 高效:多路复用I/O可以显著降低系统资源的消耗,因为它不需要为每个I/O操作创建一个单独的线程或进程。
  • 提高并发性:允许程序同时处理多个I/O操作,适用于高并发的应用程序。
  • 减少CPU消耗:相对于轮询模型,多路复用I/O会减少CPU的消耗,因为程序不必周期性地查询I/O操作的状态。

多路复用I/O的缺点:

  • 实现复杂性:使用多路复用I/O通常需要更复杂的编程模式,因为程序需要处理等待事件、处理事件和重新注册事件等任务。
  • 对不同平台的依赖性:不同操作系统可能提供不同的多路复用机制,因此需要根据目标平台选择合适的机制。

多路复用I/O适用场景:

  • 需要高效处理大量并发连接或请求的网络服务器,如Web服务器。
  • 需要提高应用程序的响应性,以便及时响应事件。
  • 希望减少资源消耗,不希望为每个连接创建一个单独的线程或进程。

多路复用I/O实现:

伪代码描述IO多路复用:

while(status == OK) { // 不断轮询
 ready_fd_list = io_wait(fd_list); //内核缓冲区是否有准备好的数据
 for(fd in ready_fd_list) {
  data = read(fd) // 有准备好的数据读取到用户缓冲区
  process(data)
 }
}

 

信号驱动I/O模型(Signal-driven I/O)

在信号驱动I/O模型中,程序会为I/O操作注册信号处理函数。

当I/O操作完成时,操作系统会向程序发送信号,程序将执行相应的处理函数。

如下图所示:

IO模型详解(5种IO模型图解)-mikechen

信号驱动I/O流程如下:

  • 开启套接字信号驱动IO功能
  • 系统调用Sigaction执行信号处理函数(非阻塞,立刻返回)
  • 数据就绪,生成Sigio信号,通过信号回调通知应用来读取数据

信号驱动I/O的优点:

  • 高效:信号驱动I/O可以显著降低系统资源的消耗,因为它不需要为每个I/O操作创建一个单独的线程或进程。
  • 提高并发性:允许程序同时处理多个I/O操作,适用于高并发的应用程序。
  • 减少CPU消耗:相对于轮询模型,信号驱动I/O会减少CPU的消耗,因为程序不必周期性地查询I/O操作的状态。

信号驱动I/O的缺点:

  • 实现复杂性:使用信号驱动I/O通常需要更复杂的编程模式,因为程序需要处理信号、注册信号处理函数以及处理已完成的I/O操作。
  • 对不同平台的依赖性:不同操作系统可能提供不同的信号处理机制,因此需要根据目标平台选择合适的机制。
  • 信号处理函数的异步性:信号处理函数在异步上下文中执行,因此需要小心处理并发问题和可重入性。

适用场景:

需要高效处理大量并发连接或请求的网络服务器,如Web服务器。

 

异步I/O模型

在异步I/O模型中,程序发起I/O操作后,可以继续执行其他操作,而不需要等待或轮询。

当I/O操作完成时,操作系统会通知程序,并将结果传递给程序的回调函数。

如下图所示:

IO模型详解(5种IO模型图解)-mikechen

异步I/O模型通常需要复杂的编程模式,但在高并发和高吞吐量的应用中表现出色。

异步I/O模型是一种高效的处理输入和输出操作的方式,允许程序发起I/O操作后可以继续执行其他操作,而不必等待或轮询操作的完成状态。

评论交流
    说说你的看法