【IO专栏】I/O 阻塞 、非阻塞、同步、异步总结

IO非JAVA独有的,想要搞明白这些原理要从根来说起,根其实就是操作系统

UNIX操作系统下面,I/O 分为5种,同步阻塞I/O;同步非阻塞IO;I/O多路复用;信号驱动I/O;异步I/O

这些名字经常听到,常常是感觉自己懂了,但是真正聊起来的时候,又不能几句话清除明了的表达出来。带着以下问题来梳理上面的名字

1.这些I/O模型有什么区别?

2.同步和阻塞似乎是同一回事,到底有啥不同?

3.什么是I/O

4.为啥需要I/O

I/O 定义

所谓I/O就是计算机内存与外部设备拷贝数据的过程,我们知道CPU访问内存的速度远远高于外部设备,因此CPU先把外部设备的数据拷贝到内存中,然后再进行处理。

请考虑一下如下场景:当你的设备通过CPU向外部设备发出一个读指令的时候,数据从外部设备拷贝到内存需要一段时间,这个时候CPU没事干了,你的程序主动把CPU让给别人?还是让CPU不停的查,数据到了吗?数据到了吗?

这就是I/O模型要解决的问题。

下面重点分析I/O模型的区别

JAVA 的I/O 模型

对于一个网络I/O通信过程,比如网络数据的读取,会涉及两个对象。一个是调用I/O操作的用户线程,另外一个就是操作系统的内核了。一个进程的地址空间分为 用户空间,内核空间。用户线程不能直接访问内核空间。

当用户发起I/O操作后,网络数据读取会经历两个步骤。

1.用户线程等待内核将数据从网卡拷贝到内核空间。

2.内核将数据从内核空间拷贝到用户空间。

各种I/O模型的区别就是他们实现这两个步骤的方式不一样。

同步阻塞

用户线程发起read调用后就阻塞了,让出CPU。内核将数据从网卡拷贝到内核,然后从内核拷贝到用户空间。再把用户线程叫醒。

同步非阻塞

用户线程不断发起read调用,数据没有到内核空间时,每次都会返回失败,直到数据到达内核空间。这一次调用后,在等待数据从内核空间拷贝到用户空间这段时间里,线程还是阻塞的。等到数据到达用户空间,把线程叫醒。

I/O多路复用

用户线程的读取分为两个步骤:

线程发起select调用,目的是问内核数据准备好了吗?等数据准备好了,用户线程再发起read调用。在等待数据从内核空间拷贝到用户空间的时间里,线程还是阻塞的。为啥叫I/O多路复用呢?因为一个select 可以向内核查询多个通道(channel)的状态。所以叫多路复用。

异步I/O

用户线程发起read调用的时候注册一个回调函数,read立即返回。当内核将数据准备好之后,再调用指定的回调函数,进行处理。在这个过程中,用户线程一直没有阻塞。

 

高并发的思路

高并发就是能够快速处理大量的请求,需要设计合理的线程模型让CPU忙起来,尽量不要让线程阻塞,因为一阻塞CPU就闲下来了。另外就是有多少任务,就需要有多少相应规模的线程数去处理。I/O 请求核心处理三件事情:

1.接收链接

2.检测I/O事件

3.处理请求

最核心的就是把这三件事给分开处理

专门的线程组来接收acceptor

专门的线程组来 检测I/O事件

具体的任务执行也有专门的线程组

重点分析

I/O模型是为了解决内存与外部设备速度差异问题。

阻塞与非阻塞

我们平时说的阻塞非阻塞是指应用程序发起I/O操作的时候是立即返回,还是等待。

同步与异步

应用程序与内核通信的时候,数据从内核空间到应用空间的拷贝,是由内核主动发起的,还是由应用程序触发的。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值