Redis中BIO、NIO、IO多路复用

Redis中BIO、NIO、IO多路复用_第1张图片

1 BIO(阻塞IO)

阻塞IO就是两个阶段都必须阻塞等待

Redis中BIO、NIO、IO多路复用_第2张图片

通常IO操作都是阻塞I/O的,也就是说当你调用read时,如果没有数据收到,那么线程或者进程就会被挂起,直到收到数据。

read直到数据复制到应用进程的缓冲区或者发生错误才会返回,这就是阻塞的定义:等待某个事件

2 NIO(非阻塞IO)

非阻塞IO的recvfrom操作会理解返回结果而不是阻塞用户进程,

Redis中BIO、NIO、IO多路复用_第3张图片
好处:如果等待的事件没有发生,如上图中所示的read数据未准备好,系统调用会立即返回而不是导致调用进程被挂起。

坏处:盲轮询(盲等)并没有提升性能,用户进程需要采用轮询的方式(逐个查找)查看事件状态,这往往耗费大量的CPU资源。

3 IO多路复用

无论是阻塞IO还是非阻塞IO,用户应用在一阶段都需要调用recvfrom来获取数据,差别在于无数据时的处理方案:

  • 如果调用recvfrom时,恰好没有数据,阻塞IO会使进程阻塞,非阻塞IO使CPU空转,都不能充分发挥CPU的作用
  • 如果调用recvfrom时,恰好数据,用户进程可以直接进入第二阶段,读取并处理数据

比如服务端处理客户端Socket请求时,在单线程情况下,只能依次处理每一个socket,如果正在处理的socket恰好未就绪(数据读取不可读或不可写),线程就会被阻塞,所有其他客户端socket都必须等待,性能自然会很差

文件描述符:简称FD,是一个从 0 开始递增的无符号整数,用来关联Linux中的一个文件。在Linux中,一切皆文件,例如常规文件、视频、硬件设备等,当然也包括网络套接字(Socket)

IO多路复用:是利用单个线程来同时监听多个FD,并在某个FD可读、可写时得到通知,从而避免无效的等待,充分利用CPU资源

Redis中BIO、NIO、IO多路复用_第4张图片

recvfrom只能监听一个FD
select可以监听多个FD

不通过监听FD的方式、通知的方式又有多种实现,常见的有

  • select
  • poll
  • epoll

区别:

  • select和poll只会通知用户进程有FD就绪,但不确定具体是哪个FD就绪,但不确定具体是哪个FD,需要用户进程逐个遍历FD来确认
  • epoll则会在通知用户进程FD就绪的同时,把已就绪的FD写入用户空间

你可能感兴趣的:(面试篇,redis,nio)