5种网络IO模型介绍

版权声明:如需转载,请附上原文链接即可 https://blog.csdn.net/doujinlong1/article/details/84068812

5种网络IO模型介绍

IO 模型分为以下几种:

阻塞IO

非阻塞IO

信号驱动IO

IO多路复用

异步IO

image0545f4a8ed4d28b9.png

前四个为同步IO

1 阻塞IO
阻塞IO模型图

一个IO操作需要两步: 等待数据和拷贝数据。

blocking IO的特点就是在IO执行的两个阶段(等待数据和拷贝数据两个阶段)都被block了。

一直阻塞,知道两步完成

2 非阻塞IO
image0f982338a87a5a98.png

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

等待数据的不用阻塞,而是轮询check,第二步阻塞。

所以,在非阻塞式IO中,用户进程其实是需要不断的主动询问kernel数据准备好了没有。

3 多路复用IO
imagefca737bac6fed2ce.png

和第二种一样,调用system call之后,并不等待内核的返回结果而是立即返回。虽然返回结果的调用函数是一个异步的方式,但应用程序会被像select、poll和epoll等具有多个文件描述符的函数阻塞住,一直等到这个system call有结果返回了,再通知应用程序。这种情况,从IO操作的实际效果来看,多路复用IO和第一种同步阻塞IO是一样的,应用程序都是一直等到IO操作成功之后(数据已经被写入或者读取),才开始进行下面的工作。不同点在于多路复用IO用一个select函数可以为多个文件描述符提供通知,提供了并发性。举个例子:例如有一万个并发的read请求,但是网络上仍然没有数据,此时这一万个read会同时各自阻塞,现在用select、poll、epoll这样的函数来专门负责阻塞同时监听这一万个请求的状态,一旦有数据到达了就负责通知,这样就将一万个等待和阻塞转化为一个专门的函数来负责与管理。

多路复用技术应用于JAVA NIO的核心类库多路复用器Selector中,目前支持I/O多路复用的系统调用有select、pselect、poll、epoll,在linux编程中有一段时间一直在使用select做轮询和网络事件通知的,但是select支持一个进程打开的socket描述符(FD)收到了限制,一般为1024,由于这一限制,现在使用了epoll代替了select,而epoll支持一个进程打开的FD不受限制。

和第二个一样,只是select可以支持并发。

4 异步IO

image0a91587b8c6f4d1b.png

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

实现了真正的非阻塞,从开始发起操作到最后读取完成,都不需要阻塞。

5 信号驱动IO

应用程序提交read请求,调用system call,然后内核开始处理相应的IO操作,而同时,应用程序并不等内核返回响应,就会开始执行其他的处理操作(应用程序没有被IO阻塞),当内核执行完毕,返回read响应,就会产生一个信号或执行一个基于线程的回调函数来完成这次IO处理过程。在这里IO的读写操作是在IO事件发生之后由应用程序来完成。

6 同步和异步的区别

异步IO与同步IO的区别在于:同步IO是需要应用程序主动地循环去询问是否有数据,而异步IO是通过像select等IO多路复用函数来同时检测多个事件句柄来告知应用程序是否有数据。

同步是需要主动等待消息通知,而异步则是被动接受消息通知,通过回调、通知、状态等方式来被动获取消息。IO多路复用在阻塞到select阶段时,用户进程是主动等待并调用select函数来获取就绪状态消息,并且其进程状态为阻塞。所以IO多路复用是同步阻塞模式。

7 阻塞和非阻塞的区别

调用一个方法,一直到拿到结果为止等待,则为阻塞。
调用一个方法,直接给你结果,则为非阻塞。

这么看来,同步和阻塞,异步和非阻塞看起来意思是一样的,但是其实不然,同步异步强调的是方法的结果如何返回,而阻塞非阻塞强调的是执行方法的过程如何执行。比如,你去餐馆吃饭,你点了一盘菜,你是继续等待还是出去等老板打电话给你说菜好了,这就是同步异步。而你时不时问老板说菜好了吗,老板可以在你问了之后回答马上好一直到最后说好了是非阻塞,而阻塞是你问了一次,老板不说话,直到菜好了端出来回答一句好了。

猜你喜欢

转载自blog.csdn.net/doujinlong1/article/details/84068812
今日推荐