网络IO模型总结

目录

网络IO模型:

阻塞IO:

非阻塞IO

多路复用IO:

异步IO:

阻塞与非阻塞、同步与异步:

信号驱动IO:

五种io对比总结:

select和epoll对比:


网络IO模型:

        网络IO的本质是socket的读取,socket在linux系统被抽象为流,IO可以理解为对流的操作。它会涉及到两个系统对象,一个是用户空间调用 IO 的进程或者线程,另一个是内核空间的内核系统, 比如发生 IO 操作 read 时,它会经历两个阶段:
1. 等待数据准备就绪
2. 将数据从内核拷贝到进程或者线程中。
因为在以上两个阶段上各有不同的情况,所以出现了多种网络 IO 模型

Unix 有五种 I/O 模型:

  • 阻塞IO(bloking IO)
  • 非阻塞IO(non-blocking IO)
  • 多路复用IO(multiplexing IO)
  • 信号驱动式IO(signal-driven IO)
  • 异步IO(asynchronous IO)

阻塞IO:

        上图是阻塞io的调用过程,当用户进程调用了 read 这个系统调用, kernel 就开始了 IO 的第一个阶段:准备数据。对于network io 来说,很多时候数据在一开始还没有到达(比如,还没有收到一个完整的数据包),这个时候 kernel 就要等待足够的数据到来。而在用户进程这边,整个进程会被阻塞。当 kernel一直等到数据准备好了,它就会将数据从 kernel 中拷贝到用户内存,然后 kernel 返回结果,用户进程才解除 block 的状态,重新运行起来。所以, blocking IO 的特点就是在 IO 执行的两个阶段(等待数据和拷贝数据两个阶段)都被block 了。

非阻塞IO

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

        从图中可以看出,当用户进程发出 read 操作时,如果 kernel 中的数据还没有准备好,那
么它并不会 block 用户进程,而是立刻返回一个 error。从用户进程角度讲 ,它发起一个
read 操作后,并不需要等待,而是马上就得到了一个结果。用户进程判断结果是一个 error
时,它就知道数据还没有准备好,于是它可以再次发送 read 操作。一旦 kernel 中的数据
准备好了,并且又再次收到了用户进程的 system call,那么它马上就将数据拷贝到了用
户内存,然后返回, 所以,在非阻塞式 IO 中,用户进程其实是需要不断的主动询问 kernel
数据准备好了没有。

多路复用IO:

        IO multiplexing 这个词可能有点陌生,但是提到 select/epoll,大概就都能明白了。有些地方
也称这种 IO 方式为事件驱动 IO(event driven IO)。我们都知道, select/epoll 的好处就在于单
个 process 就可以同时处理多个网络连接的 IO。它的基本原理就是 select/epoll 这个 function
会不断的轮询所负责的所有 socket,当某个 socket 有数据到达了,就通知用户进程。它的流程如图:

        当用户进程调用了 select,那么整个进程会被 block,而同时, kernel 会“监视”所有 select 负责的 socket,当任何一个 socket 中的数据准备好了, select 就会返回。这个时候用户进程再调用 read 操作,将数据从 kernel 拷贝到用户进程。这个图和 blocking IO 的图其实并没有太大的不同,事实上还更差一些。因为这里需要使用两个系统调用(select 和 read),而 blocking IO 只调用了一个系统调用(read)。但是使用 select 以后最大的优势是用户可以在一个线程内同时处理多个 socket 的 IO 请求。用户可以注册多个 socket,然后不断地调用 select 读取被激活的 socket,即可达到在同一个线程内同时处理多个 IO 请求的目的。而在同步阻塞模型中,必须通过多线程的方式才能达到这个目的。(多说一句:所以,如果处理的连接数不是很高的话,使用select/epoll 的 web server 不一定比使用 multi-threading + blocking IO 的 webserver 性能更好,可能延迟还更大。 select/epoll 的优势并不是对于单个连接能处理得更快,而是在于能处理更多的连接。) 

        在多路复用模型中,对于每一个 socket,一般都设置成为 non-blocking,但是,如上图示,整个用户的 process 其实是一直被 block 的。只不过 process 是被 select 这个函数 block,而不是被 socket IO 给 block。因此 select()与非阻塞 IO 类似。

异步IO:

         Linux 下的 asynchronous IO 用在磁盘 IO 读写操作,不用于网络 IO,从内核 2.6 版本才开始引入。先看一下它的流程。

                

        用户进程发起 read 操作之后,立刻就可以开始去做其它的事。而另一方面,从 kernel
的角度,当它受到一个 asynchronous read 之后,首先它会立刻返回,所以不会对用户进
程产生任何 block。然后, kernel 会等待数据准备完成,然后将数据拷贝到用户内存,当
这一切都完成之后, kernel 会给用户进程发送一个 signal,告诉它 read 操作完成了。

阻塞与非阻塞、同步与异步:

        同步和异步关注的是消息通信机制,阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态。 

        所谓同步,就是在发出一个调用时,在没有得到结果之前,该调用就不返回。但是一旦调用返回,就得到返回值了。换句话说,就是由调用者主动等待这个调用的结果。而异步则是相反,调用在发出之后,这个调用就直接返回了,所以没有返回结果。换句话说,当一个异步过程调用发出后,调用者不会立刻得到结果。而是在调用发出后,被调用者通过状态、通知来通知调用者,或通过回调函数处理这个调用。

        阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。

信号驱动IO:

       首先我们允许套接口进行信号驱动 I/O,并安装一个信号处理函数,进程继续运行并不阻
塞。当数据准备好时,进程会收到一个 SIGIO 信号,可以在信号处理函数中调用 I/O 操作函
数处理数据。当数据报准备好读取时,内核就为该进程产生一个 SIGIO 信号。我们随后既可
以在信号处理函数中调用 read 读取数据报,并通知主循环数据已准备好待处理,也可以立
即通知主循环,让它来读取数据报。无论如何处理 SIGIO 信号,这种模型的优势在于等待数
据报到达(第一阶段)期间,进程可以继续执行,不被阻塞。免去了 select 的阻塞与轮询,当
有活跃套接字时,由注册的 handler 处理。
 

五种io对比总结:

  • 只有aio才是全程非阻塞,其它4种都是同步IO。
  • 阻塞IO编程简单,这种方式使用很广泛,但是效率较低。
  • 非阻塞IO效率较高,但是编程较复杂,有开发语言和代码库支持就简单多了。
  • 多路复用非阻塞IO效率比非阻塞IO更高,在大规模的网络IO处理中尤其明显,支持的程序也越来越多。
  • 异步IO效率很高,但是编程很复杂。

select和epoll对比:

     select不足的地方:

  1.  每次select都要把全部IO句柄复制到内核
  2.  内核每次都要遍历全部IO句柄,以判断是否数据准备好
  3.  select模式最大IO句柄数是1024,太多了性能下降明显

     epoll的特点:

  1.  每次新建IO句柄(epoll_create)才复制并注册(epoll_register)到内核
  2.  内核根据IO事件,把准备好的IO句柄放到就绪队列
  3.  应用只要轮询(epoll_wait)就绪队列,然后去读取数据

只需要轮询就绪队列(数量少),不存在select的轮询,也没有内核的轮询,不需要多次复制所有的IO句柄。因此,可以同时支持的IO句柄数轻松过百万。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值