目录
I/O的概念
网络通信的本质
网络通信的本质其实就是I/O
- I:表示input(输入)
- O:表示output(输出)
- 网络通信时,双方主机中的两个进程本质上就是从套接字中拿取或放入数据,它们的本质是I/O
- 网络中的各种协议,本质上就是规定网络通信时是如何I/O的
I/O的本质
我们所谈的I/O,都是站在内存的角度
- 对于输入来说,本质就是数据从外设放到内存里
- 对于输出来说,本质上就是数据从内存到外设里
- 以读文件为例,本质上不就是把磁盘上的文件数据读取到内存中
I/O的本质:I/O = 等 + 拷贝
- 以recv为例,我们调用recv的时候,若内核发送缓冲区中没有数据,那么执行流会进行阻塞等待。 若内核发送缓冲区中有了数据,那么recv会把数据拷贝到用户层
- 其实不管是哪些函数,printf/scanf/read/write....,它们都会进行等待以及拷贝。所以I/O的本质是等+拷贝
- 等:本质上就是等待I/O的条件就绪
高效I/O
I/O = 等 + 拷贝,所以I/O的时间是由等的时间和拷贝的时间决定的,什么叫做高效I/O呢?
- 对于拷贝的时间,我们是无法从软件方面进行优化的,因为拷贝的速度是由硬件架构所决定的
- 对于等待的时间,我们可以从软件方面优化
- 所以我们所说的I/O效率比较低,大多数情况指的是I/O的等待时间较长
所以对于高效的I/O来说,就是尽可能的减少等待的时间, 即单位时间内,等的比重越低,那么I/O的效率越高!
程序员进行编程时,什么叫做高效的代码?
- 减少I/O的比重
- 若无法减少I/O的比重,那么尽可能把I/O进行等待的时间利用起来
五种I/O模型
从理论回归到日常生活,其实我们日常生活中是有与I/O非常相似的例子,例如钓鱼
- I/O = 等 + 拷贝,钓鱼 = 等 + 钓
当我们去钓鱼的时候,首先把鱼钩丢入湖水中,然后一直等待,直到鱼咬钩就把鱼拉上来,放入到水桶中
- 湖水类比OS内部缓冲区
- 水桶类比用户缓冲区
- 鱼类比数据
- 鱼钩/鱼竿类比一个sockfd
接下来让我们从钓鱼的角度理解五种I/O模型
阻塞I/O
阻塞I/O:
- 你把鱼钩和鱼饵放入水中后,完全专注于等待鱼上钩,整个过程中你什么也不做,无法去干其他事情。如果没有鱼上钩,你只能继续等,直到鱼上钩为止。
- 在阻塞I/O模型中,程序在发起I/O请求后,会被阻塞(即停下来)直到I/O完成。程序不能做其他事情,必须等到数据完全准备好才会继续运行。
- 这是最简单也是最直观的I/O模型,最常见于简单的单线程程序中。它的缺点是等待期间资源不能被其他任务使用,效率较低。
非阻塞I/O