IO模型


I/O

I/O介绍

I/O(input/out)即输入/输出

常见的I/O模型

有5种:同步阻塞I/O,同步非阻塞I/O,I/O多路复用,信号驱动I/O与异步I/O

常见I/O

传统IO是一次一个字节处理数据

BIO(Blocking I/O)

同步阻塞I/O 应用程序发起read调用后,会一直阻塞,直到把内核数据拷贝到用户空间

NIO(Non-Blocking/ New I/O)

同步非阻塞I/O 是以块(缓冲区)的形式处理数据。最主要的是NIO可以实现非阻塞

NIO有3个核心部分组成。分别是Buffer(缓冲区)、Channel(管道)以及Selector(选择器),可以简单理解为:Buffer是存储数据的地方,Channel是运输数据的载体,而Selector用于检查多个Channel的状态变更情况

应用程序会一直发起read调用,等待数据从内核空间拷贝到用户空间的这段时间里,线程依旧是阻塞的,直到在内核把数据拷贝到用户空间

NIO抽象出了新的通道(Channel)作为输入输出的通道,并且提供了缓存(Buffer)的支持,在进行读操作时,需要使用Buffer分配空间,然后将数据从Channel中读入Buffer中,对于Channel的写操作,也需要现将数据写入Buffer,然后将Buffer写入Channel中。

AIO(Asynchronous I/O)

异步IO模型 基于事件和回调机制实现,应用操作之后会直接返回,不会堵塞,后台处理完成后,操作系统会通知相应的线程进行后续操作。

总结

IO多路复用模型

线程首先发起select调用,询问内核数据是否准备就绪,等内核把数据准备好了,用户线程再发起read调用。read调用过程还是阻塞的。

通过一个进程监听多个文件描述符,一旦某个文件描述符准备就绪,就去通知程序做相对应的处理。这种以通知的方式,优势并不是对与单个连接能处理的比较快,而是能处理更多的连接。

Linux对文件的操作时机就是通过文件描述符(fd)

select/poll/epoll

  • select 它支持最大的连接数是1024或2048,因为再select函数下要传入fd_set参数,这个fd_set的大小要么1024或2048(其实就看操作系统的位数) 。

fd_set就是bitmap的数据结构,可以简单理解为只要位为0,那说明还没数据到缓冲区,只要位为1,那说明数据以及到缓冲区。而select函数做的就是每次将fd_set遍历,判断标志位有没有发生变化,如果有变化则通知程序做终端处理。

  • epoll 它不存在最大连接数的限制,不像select函数每次把所有文件的描述符都遍历,简单理解就是epoll把就绪的文件描述符专门维护了一块空间,每次就从就绪列表里拿,不需要对所有文件描述符进行遍历。



Enjoy Reading This Article?

Here are some more articles you might like to read next:

  • 2379. Minimum Recolors to Get K Consecutive Black Blocks
  • 2471. Minimum Number of Operations to Sort a Binary Tree by Level
  • 1387. Sort Integers by The Power Value
  • 2090. K Radius Subarray Averages
  • 2545. Sort the Students by Their Kth Score