专业简历制作网站推荐,wordpress页面目录下,做网站需要学什么专业,域名建网站公司IO是什么#xff1f;
IO分为两类#xff0c;它们之间是有区别的#xff0c;而且有很大的区别#xff1b;1. 文件系统的IO
也叫本地io#xff0c;就是和磁盘或者外围存储设备进行读写操作#xff0c;外围设备有USB、移动硬盘等等#xff1b;2. 网络的IO
将数据发送给对方…IO是什么
IO分为两类它们之间是有区别的而且有很大的区别1. 文件系统的IO
也叫本地io就是和磁盘或者外围存储设备进行读写操作外围设备有USB、移动硬盘等等2. 网络的IO
将数据发送给对方 和 读取对方的数据就称为网络IO网络IO是如何连接的
网络IO就是本机的应用程序对着内核的缓冲区读写的过程发送数据时应用程序会将数据复制到内核态的写队列中再由内核将数据复制到网卡然后进行发送读取数据则反过来网卡接受到数据后将数据复制到内核态的读队列中在通知应用程序来获取数据下面是一次网络读取内容的I/O示意图数据先从外设网卡到内核空间再到用户空间JVM最后到应用程序的一个过程。
上述一次I/O读取所谓的阻塞和非阻塞体现在哪里呢
Java最早期的版本的I/O就是这样实现的。当程序调用到读取I/O的时候同步阻塞住程序直到数据从网卡写入内核空间在写入用户空间才返回数据程序才可以继续进行。
BIO BIO为同步阻塞IOblocking queue的简写也就是说多线程情况下只有一个线程操作内核的queue当前线程操作完queue后才能给下一个线程操作 如图1所示用户线程通过系统调用read发起IO读操作由用户空间转到内核空间。内核等到数据包到达后然后将接收的数据拷贝到用户空间完成read操作。
用户线程使用同步阻塞IO模型的伪代码描述为
{read(socket, buffer);process(buffer);}即用户需要等待read将socket中的数据读取到buffer后才继续处理接收的数据。整个IO请求的过程中用户线程是被阻塞的这导致用户在发起IO请求时不能做任何事情对CPU的资源利用率不够。
在BIO下一个连接就对应一个线程如果连接特别多的情况下就会有特别多的线程很费线程在早期的时候世界上的计算机还很少网站也少会上网的人更是寥寥无几并发最高的时候也就几十上百个所以当并发量不高的情况下BIO也够用了
NIO 流程图 Non-blocking IO的简写同步非阻塞IO内核发生了变化app访问内核的缓冲区时不会阻塞但是返回值需要用户自己判断如果连接数特别多的i情况下就需要应用程序不停遍历一个个进行状态的判断询问是否有数据到达 如图2所示由于socket是非阻塞的方式因此用户线程发起IO请求时立即返回。但并未读取到任何数据用户线程需要不断地发起IO请求直到数据到达后才真正读取到数据继续执行。
用户线程使用同步非阻塞IO模型的伪代码描述为
{while(read(socket, buffer) ! SUCCESS);process(buffer);
}即用户需要不断地调用read尝试读取socket中的数据直到读取成功后才继续处理接收的数据。整个IO请求的过程中虽然用户线程每次发起IO请求后可以立即返回但是为了等到数据仍需要不断地轮询、重复请求消耗了大量的CPU的资源。一般很少直接使用这种模型而是在其他IO模型中使用非阻塞IO这一特性。
IO 多路复用
多路是指网络连接复用指的是同一个线程为什么有IO多路复用机制?
没有IO多路复用机制时有BIO、NIO两种实现方式但有一些问题IO多路复用模型是建立在内核提供的多路分离函数select基础之上的使用select函数可以避免同步非阻塞IO模型中轮询等待的问题。 如图3所示用户首先将需要进行IO操作的socket添加到select中然后阻塞等待select系统调用返回。当数据到达时socket被激活select函数返回。用户线程正式发起read请求读取数据并继续执行。
从流程上来看使用select函数进行IO请求和同步阻塞模型没有太大的区别甚至还多了添加监视socket以及调用select函数的额外操作效率更差。但是使用select以后最大的优势是用户可以在一个线程内同时处理多个socket的IO请求。用户可以注册多个socket然后不断地调用select读取被激活的socket即可达到在同一个线程内同时处理多个IO请求的目的。而在同步阻塞模型中必须通过多线程的方式才能达到这个目的。
用户线程使用select函数的伪代码描述为
{select(socket);while(1) {sockets select();for(socket in sockets) {if(can_read(socket)) {read(socket, buffer);process(buffer);}}}}其中while循环前将socket添加到select监视中然后在while内一直调用select获取被激活的socket一旦socket可读便调用read函数将socket中的数据读取出来。
然而使用select函数的优点并不仅限于此。虽然上述方式允许单线程内处理多个IO请求但是每个IO请求的过程还是阻塞的在select函数上阻塞平均时间甚至比同步阻塞IO模型还要长。如果用户线程只注册自己感兴趣的socket或者IO请求然后去做自己的事情等到数据到来时再进行处理则可以提高CPU的利用率。