Java中的IO模型

一、同步、异步、阻塞与非阻塞

       从内核角度看I/O操作分为两步:用户层API调用;内核层完成系统调用(发起I/O请求)。所以同步、异步针对的是用户的API的调用;阻塞、非阻塞针对的是IO请求。

      同步指的是函数完成之前会一直等待;阻塞指的是系统调用的时候进程会被设置为sleep状态,直到等待的数据发生       

       同步与异步:

       实际上同步与异步是针对应用程序与内核的交互而言的。同步过程中进程触发IO操作并等待或者轮询的去查看IO操作是否完成。异步过程中进程触发IO操作以后,直接返回,做自己的事情,IO交给内核来处理,完成后内核通知进程IO完成。

       阻塞与非阻塞

       若要做一件事情,能不能立即得到返回应答,如果不能立即获得返回,需要等待,就是阻塞;否则就是非阻塞。

二、Unix提供的I/O模型

分为五种:阻塞IO、非阻塞IO、IO复用、信号驱动IO、异步IO

首先我们以一个示例对这五种IO模型进行说明。

事情:演唱会

角色1:售票处

角色2:小明

角色3:黄牛

角色4:快递员

阻塞IO:

小明到售票处进行购票,票还未到发售时间,在售票处等待三天,直到买到票返回

非阻塞IO:

小明到售票处进行购票,票还未到发售时间,小明回家,过三个小时再来问一次,如此反复,直到买到票回家

IO复用:

小明给黄牛打电话,帮小明留意买张票,票买到后黄牛打电话告诉小明,小明来取票回家;票没有出来之前,小明就直接做自己的事情

信号驱动IO:

小明想看演唱会,直接给售票处打电话说明,有票打电话通知一声,小明去取票;票没有出来之前,小明就直接做自己的事情

异步IO:

小明想看演唱会,直接给售票处打电话说明,有票直接让快递员送一张票

阻塞IO:

BIO:称为同步阻塞IO。一个用户连接请求创建一个线程进行处理,它的缺点是用户请求数量和服务端的线程数有很大关系,服务端的线程是并发的瓶颈,限制了服务器用户的数量。

分为两个阶段:

(1)等待数据就绪,网络I/O就是等待远端数据陆续到达,磁盘I/O就是等待磁盘数据从磁盘上读取到内核态中;

(2)数据拷贝,将内核空间的数据拷贝一份到用户态中。

 

非阻塞IO:

非阻塞IO分为三个阶段:

(1)socket设置为NONBLOCK就是告诉内核,当I/O请求无法完成时,不要将线程设置为sleep状态,而是返回一个错误码(EWOULDBLOCK),这样线程就不会阻塞了;

(2)I/O操作函数会一直测试数据是否准备好,若没有准备好,继续测试,直到准备好;整个I/O请求过程中,虽然用户线程每次发起请求都会立即返回,但为了等到数据,仍要不断轮询,重复请求,浪费大量CPU资源;

(3)数据准备好了,将其从用户空间拷贝到内核空间。


IO复用:

       I/O多路复用会用到select函数和poll函数,这两个函数会使线程阻塞,与阻塞I/O不同的是:I/O多路复用可以同时对多个I/O操作进行阻塞,还可以同时对多个读操作,多个写操作的I/O函数进行检测,直到有数据可读或者可写,才真正调用I/O函数。

       从流程上来看,使用select函数进行I/O请求和同步阻塞模型没有太大的区别,甚至还多了添加监视Channel,以及调用select函数的额外操作,增加了额外工作。但是,使用 select以后最大的优势是用户可以在一个线程内同时处理多个Channel的I/O请求。用户可以注册多个Channel,然后不断地调用select读取被激活的Channel,即可达到在同一个线程内同时处理多个I/O请求的目的。而在同步阻塞模型中,必须通过多线程的方式才能达到这个目的。

       调用select/poll该方法由一个用户态线程负责轮询多个Channel,直到某个阶段1的数据就绪,再通知实际的用户线程执行阶段2的拷贝。 通过一个专职的用户态线程执行非阻塞I/O轮询,模拟实现了阶段一的异步化。


信号驱动IO

       首先我们允许socket进行信号驱动I/O,并安装一个信号处理函数,线程继续运行并不阻塞。当数据准备好时,线程会收到一个SIGIO 信号,可以在信号处理函数中调用I/O操作函数处理数据。

 

异步IO

       调用aio_read 函数,告诉内核描述字,缓冲区指针,缓冲区大小,文件偏移以及通知的方式,然后立即返回。当内核将数据拷贝到缓冲区后,再通知应用程序。所以异步I/O模式下,阶段1和阶段2全部由内核完成,完成不需要用户线程的参与。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值