所有io全面了解,就不信你看不懂

什么是io呢?

IO其实就是输入输出,平时有听过磁盘IO,网络IO,java IO吧,那这些都是什么意思呢?往下看。

磁盘IO

啥意思?输入输出,从磁盘读数据到内存算输入,将内存数据写进磁盘算输出。

网络IO

啥意思?还是输入输出,比如:当我们需要去请求一个网页的时候就需要通过网络IO,当我们请求一个网页,浏览器首先会将数据发送到对应网页的服务器上,这就是输出,当服务器将网页发回来,这就是输入。

操作系统IO

磁盘IO和网络IO我们的应用程序肯定是不能直接操作的,故我们需要借用操作系统来实现我们的具体IO操作。以linux操作系统来看:它为每一个进程都分配了内存空间,而内存空间又分为了用户空间和内核空间,为什么要分嘞?和前面一样,我们的进程肯定是不能够直接操作内核的,如果每个进程都能直接操作,那程序崩溃肯定是很经常的。
所以进程执行IO需要分为两个阶段:
1.IO调用:用户进程发起IO调用。
2.IO执行:内核执行IO。
IO执行还分为两个阶段:
1.数据准备:内核等待IO设备准备好数据读取到内核缓冲区。
2.数据拷贝:将数据从内核缓冲区拷贝到用户进程缓冲区。
如图:
在这里插入图片描述

IO模型

IO模型是针对操作系统IO来说的。IO模型有五种:同步阻塞IO,同步非阻塞IO,多路复用IO,信号驱动IO,异步IO。

同步阻塞IO

先来看张图:
在这里插入图片描述
那么什么是同步阻塞IO呢?
同步:线程启动一个IO操作后就进入了等待状态,直到IO操作完成之后才醒来执行。
阻塞:如图,应用进程在发起IO调用到开始处理数据报的这一期间只能够阻塞

同步非阻塞IO

先来看张图:
在这里插入图片描述
那么什么是同步非阻塞IO呢?
同步已经在上面讲过了,非阻塞就是:
非阻塞:如图,应用进程在发送IO调用后,内核如果没有准备好就会回送EWOULDBLOCK错误码,再之后应用进程会再次发起调用,这叫做轮询,直到内核数据准备好。
这时应用进程是没有被阻塞的,并且在轮询的过程中还可以去做别的事情。

同步多路复用IO

来看张图:

多路复用IO其实就是非阻塞IO的升级版,非阻塞IO会进行多次无效的轮询,这无疑是很耗系统资源的,故为解决这个问题,只要让内核数据准备好了再通知应用进程就好了。所以采用了select,应用程序去调用select去监控内核,只要有数据报准备好就会返回可读状态,然后recvfrom再去读取数据。
使用select的话是有一些问题的,比如:它监听的IO最大连接数有限,需要去遍历所有流找到准备好的。
故为解决最大连接数,提出了poll,为解决遍历问题,提出了epoll。具体的就不用太了解了。
但是还是有一些问题epoll还是需要去看数据是否准备就绪,故提出一种当数据准备好了直接通知,所以有了信号驱动IO。

同步信号驱动IO

来看张图:
在这里插入图片描述
信号驱动IO就不会主动去询问数据是否准备好了,而是调用sigaction发送了一个SIGIO信号,这时应用程序可以去做别的事,当数据准备好了之后,再通过SIGIO通知应用进程,然后应用进程再去获取数据。但是呢,数据从内核空间拷贝到用户空间的过程中还是阻塞的,所以有了异步IO。

异步IO

来看张图:
在这里插入图片描述
当用户进程去调用IO时,会立即返回类似提交成功的提示,等待内核数据处理完成再发送信号通知用户进程IO操作完毕。

java IO

那么讲了这么多,学习java的可能还不是特别懂,比如我,那么java里面的那些BIO,NIO,AIO是什么呢?
其实就是与socket有关。
我们先来讲讲java处理网络请求的过程
1.客户端发送请求数据到服务端网卡,linux通过网卡读取数据到内核缓冲区。
2.服务端从内核缓冲区读取到用户进程空间。
3.服务端在自己的用户空间处理客户端的请求。
4.服务端将构建好的响应从用户进程空间写入到内核缓冲区。
5.内核通过网络IO,将内核缓冲区的数据写入网卡,然后网卡再将数据发送给客户端。

BIO(同步阻塞IO)

先来看张图:
在这里插入图片描述
这是最经典的java实现同步阻塞IO的模型,其实原理就是使用socket,客户端来请求之后,服务端去处理,当服务端使用read其实就是去读客户端的数据。但是这样会有一个问题,当如果第一个客户端连接之后什么事也不干,卡在那里,那么第二个请求进来也处理不了,所以优化一下:
在这里插入图片描述
根据这样的设计,客户端进来,服务端就会新建一个线程去处理客户端的数据。但是这样的话就会使资源的消耗增大,毕竟有多少个客户端请求就创建多少个线程。所以就出现了接下来要讲的NIO。

NIO(同步非阻塞IO)

先来看张图:
在这里插入图片描述
这就是java中实现同步不阻塞IO的模型,使用的是SocketChannel以及ServerSocketChannel,还使用了Selector选择器。当客户端来了之后会被注册到selector轮询器中,轮询器会去判断是否有请求时间发生、读数据发生、写数据发生,如果都没有的话,那么轮询器就阻塞等待,线程就阻塞,然后让出CPU资源。

AIO(异步IO)

当客户端来了之后,直接返回提交成功,等服务端处理完之后回送一个完成的信号,其实就是前面讲的异步IO模型,只是通过java去实现,使用了AsynchronousSocketChannel 以及AsynchronousServerSocketChannel ,并基于Future。

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值