网络编程之五种I/O模型

在网络编程中有5中I/O模型,今天我们就来聊一聊这5中模型的原理和区别。

1.阻塞I/O模型。

阻塞I/O模型通信示意图如下:

阻塞I/O模型通信示意图

当用户调用了recvfrom这个系统调用后,内核就开始准备数据。对于网络I/O来说,很多时候数据还没有到达,这个时候要等足够的数据到来。而在这个时候,用户的进程会被阻塞,当数据准备好的时候,它就会将数据从内核拷贝到用户内存,然后返回结果,用户进程这时候才会解除阻塞的状态,重新运行起来。在阻塞I/O模型中,进程阻塞挂起不消耗cpu的资源,及时响应每个操作。适用于并发量小的网络应用开发。对于并发量大的应用,需要为每一个请求分配一个处理进程,系统开销大。

2.非阻塞I/O模型。

非阻塞I/O模型通信示意图如下:

非阻塞I/O模型通信示意图

在非阻塞I/O模型中,当用户进程发出read操作时,如果内核中的数据还没有准备好,那么它并不会阻塞用户进程,而是立刻返回一个error。从用户进程角度来讲,发起一个read操作,并不需要等待,而是马上就得到了一个结果。当用户进程判断得到一个error后,知道内核还没有准备好数据,于是再次发送read操作,一旦内核准备好了数据并且收到了用户进程的调用,他马上就会把数据拷贝到用户内存,然后返回。在这种模型中,用户进程需要不断的询问内核是否准备好,消耗cpu的资源,适合并发量较小且不需要及时响应的网络应用开发。

3.多路复用I/O模型。

多路复用I/O模型示意图如下:

多路复用I/O模型通信示意图

在多路复用I/O模型中,多个进程的I/O可以注册到一个复用器(Selector)上,当用户进程调用这个Selector,如果Selector监听的所有I/O在内核缓冲区中都没有可读数据,select调用进程就会被阻塞,而当任意I/O在内核缓冲区中有数据时,select调用就会返回,而后select调用进程可以自己或者通知另外的进程再次发起读取I/O,读取内核中准备好的数据。

多路复用模型相对于非阻塞模型来说,需要2个系统调用(recvfrom和select),但是Selector的优势在于一次能够处理多个连接,当连接很多的时候优势是很明显的,但是单个连接并不能处理的更快。多路复用模型适合高并发的服务器开发。

4.信号驱动I/O模型。

信号驱动I/O模型通信示意图如下:

信号驱动I/O模型示意图

信号驱动模型是指进程向内核注册一个信号处理函数,然后用户进程返回不阻塞,当内核数据就绪时,返回一个信号给进程,用户进程便在处理函数中调用I/O读取数据。实际上I/O内核拷贝到用户进程的过程还是阻塞的,这种模式并没有实现真正的阻塞,是一种伪异步,实际中并不常用。

5.异步I/O模型。

异步I/O模型通信示意图如下:

异步I/O通信模型示意图

用户进程发起aio_read操作后,给内核传递与read相同的描述符、缓冲区指针、缓冲区大小三个参数及文件偏移,告诉内核但整个操作完成时,如何通知我们立刻就可以开始去做其他的事情,从内核的角度来讲,当它收到一个aio_read后,首先它会立刻返回,所以不会对用户进程产生阻塞,内核会准备等待数据准备完成,然后将数据拷贝到用户内存,当这一切都完成之后,内核会给用户进程发送一个信号,告诉它aio_read操作完成。

异步I/O的机制是:告诉内核启动某个操作,并让内核在整个操作完成通知我们,它实现了真正的异步操作,是真正的异步模型,适合高性能高并发的应用。

猜你喜欢

转载自blog.csdn.net/wzs535131/article/details/107599887