网络I/O模型
1,概念:
I/O,就是input/output,也就是输入输出。
比如对一个文件,一个socket 的写入/读取就是一个i/o
磁盘i/o,操作文件的i/o,比如给文件写入数据,读取数据
网络i/o,对一个socket连接的i/o,比如一个tcp连接,客户端和服务端的写入,读取
注意:本文的I/O模型只讨论网络I/O
2,五大I/O模型
1总览
对于网络I/O操作,抽象了五大I/O模型,分别是
1,阻塞I/O
2,非阻塞I/O
3,I/O多路复用
4,信号驱动I/O
5,异步I/O
2详情
1,阻塞I/O (blocking i/o)
应用程序在发出接收数据请求(recvfrom)后,如果数据没有准备就绪,则当前进程会一直
等待到数据准备就绪后再开始处理数据。等待期间进程是阻塞的,不能干其他事情,整个过程中
就是傻傻等待的状态。也是最简单的一种I/O模型
生活实例:
一个人在钓鱼,鱼没有上钩的时候,人一直在傻傻等待。
2,非阻塞I/O (non-blocking i/o)
应用程序在发出数据接收请求后,会把当前套接字设置为非阻塞,也就是说当前请求能否接收到
数据都不会阻塞接下来需要执行的任务。
如果要获取到数据,需要客户端后续不断轮询请求直到接收到数据。
生活实例:
一个人把鱼竿扔进水里之后,玩手机去了,每隔一段时间看看鱼上钩了没有
3,I/O多路复用 (multiplexing i/o)
I/O多路复用,比如有多个socket连接发出了接收数据的请求,按照正常的阻塞i/o的话,会按照
顺序等待这些socket一个一个数据就绪之后,逐个返回。多路复用的话,服务端会在当前进程轮询
管理这些socket,再把可用socket返回数据。不可用的socket轮询继续监听。
注意这些socket连接是非阻塞的,但是当前维护socket的进程会阻塞。也就是说socket都不可用
的时候,就会阻塞等到第一个可用socket的出现
生活实例:
十个鱼竿扔到水里,然后看着哪个鱼竿上钩了,就钓哪条。
4,信号驱动I/O (signal-driven i/o)
但应用程序发送数据接受请求同时会给当前请求注册一个信号函数。然后当前程序执行后续操作,
等到数据准备就绪后,内核就会给应用程序发送一个信号,便可以执行信号函数中的操作(信号函
数中处理接收数据的事情)
生活实例:
给鱼竿装一个传感器,玩手机去了,鱼上钩的时候传感器响了,然后再把鱼拉上来
5,异步I/O
前面四种I/O复用模型都是同步的,区别于异步I/O模型。
应用程序发送一个接受数据请求,告知系统内核并且让内核做整个(I/O)操作,操作完成后通知应用程序。
这里和信号模型有点像,具体的区别就是,信号模型下,数据就绪后通知应用程序,让应用程序来
完成I/O操作。而异步,是通知应用程序我已经完成了I/O操作,也就是应用程序和发起的i/o操作
是异步完成的,应用程序做自己的事情,内核帮助应用程序完成i/o操作。
生活实例:
异步实现要依赖底层支持,类似生活实例中钓鱼就需要一个团队的支持,把团队比作操作系统
内核,把鱼竿仍水里之后就玩手机去了,团队成员帮你钓鱼,钓上来鱼之后,告诉你一声。鱼
钓出来了。你看,你接下来执行的任务和钓鱼完全是异步的。这就是异步I/O