Java面试知识点(四十一)I/O 模型 ——阻塞、非阻塞、多路复用、异步

154 篇文章 5 订阅
150 篇文章 6 订阅

正在执行的进程,由于期待的某些事件未发生,如请求系统资源失败、等待某种操作的完成、新数据尚未到达或无新工作做等,则由系统自动执行阻塞原语 (Block),使自己由运行状态变为阻塞状态。

1.阻塞I/O

通常 IO 操作都是阻塞 I/O 的,也就是说当你调用 read 时,如果没有数据收到,那么线程或者进程就会被挂起,直到收到数据。阻塞的意思,就是一直等着。阻塞 I/O 就是等着数据过来,进行读写操作。应用的函数进行调用,但是内核一直没有返回,就一直等着。应用的函数长时间处于等待结果的状态,我们就称为阻塞 I/O。
在这里插入图片描述

2.非阻塞I/O

这时,当你调用 read 时,如果有数据收到,就返回数据,如果没有数据收到,就立刻返回一个错误,如 EWOULDBLOCK。这样是不会阻塞线程了,但是你还是要不断的轮询来读取或写入
在这里插入图片描述

(1)当用户进程发出 read 操作时,如果 kernel 中的数据还没有准备好;

(2)那么它并不会 block 用户进程,而是立刻返回一个 error,从用户进程角度讲 ,它发起一个 read 操作后,并不需要等待,而是马上就得到了一个结果;

(3)用户进程判断结果是一个 error 时,它就知道数据还没有准备好,于是它可以再次发送 read 操作。一旦 kernel 中的数据准备好了,并且又再次收到了用户进程的 system call;

(4)那么它马上就将数据拷贝到了用户内存,然后返回。

所以,nonblocking IO 的特点是用户进程在内核准备数据的阶段需要不断的主动询问数据好了没有

3.多路复用

多路复用是指使用一个线程来检查多个文件描述符(Socket)的就绪状态,比如调用 select 和 poll 函数,传入多个文件描述符(FileDescription,简称 FD),如果有一个文件描述符(FileDescription)就绪,则返回,否则阻塞直到超时。得到就绪状态后进行真正的操作可以在同一个线程里执行,也可以启动线程执行(比如使用线程池)。

在这里插入图片描述
(1)当用户进程调用了 select,那么整个进程会被 block;

(2)而同时,kernel 会 “监视” 所有 select 负责的 socket;

(3)当任何一个 socket 中的数据准备好了,select 就会返回;

(4)这个时候用户进程再调用 read 操作,将数据从 kernel 拷贝到用户进程。

所以,I/O 多路复用的特点是通过一种机制一个进程能同时等待多个文件描述符,而这些文件描述符(套接字描述符)其中的任意一个进入读就绪状态,select() 函数就可以返回。

4.异步I/O

(1)用户进程发起 read 操作之后,立刻就可以开始去做其它的事。

(2)而另一方面,从 kernel 的角度,当它受到一个 asynchronous read 之后,首先它会立刻返回,所以不会对用户进程产生任何 block。

(3)然后,kernel 会等待数据准备完成,然后将数据拷贝到用户内存,当这一切都完成之后,kernel 会给用户进程发送一个 signal,告诉它 read 操作完成了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值