网站首页 > 精选教程 正文
IO模型是一个与多线程并发密切相关的概念,本文重点介绍IO模型的几个基本概念,阻塞与非阻塞,同步与异步。
阻塞与非阻塞
阻塞和非阻塞关注的是程序(线程或进程)在等待调用结果时的状态,一般可能是等待I/O操作的结果。
阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回或继续执行。当前线程被挂起以后,CPU可以处理其他线程。
默认情况下,所有套接字都是阻塞的。进程调用 recvfrom() 后挂起,内核等待外部IO响应,IO完成传送数据到内核buffer,数据再从内核buffer复制到用户空间。
非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程,当前线程会继续往下执行。线程虽然可以处理别的事情,但还需要不断轮询,去看看调用是否已经有结果。
在上图的非阻塞IO模型中,应用进程没有阻塞,也就是没有挂起,进程一直在check数据有没有传送到内核buffer中。这种情况下进程一直占据CPU,造成忙等的结果。
以餐厅点餐做类比,阻塞IO属于店内排队就餐,非阻塞IO可以不用排队,但点完餐之后,是不是得要去看一下,我点的东西可以取了吗。
同步与异步
同步与异步关注的是程序(线程与进程)与内核调用之间的消息同步机制,与阻塞、非阻塞所关注的对象不同,这一点要注意区分。
所谓同步,就是在线程发起一个调用(I/O操作)时,在没有得到结果之前,该调用就不返回。但是一旦调用返回,就得到返回值了。
所谓异步,就是线程发起调用之后,这个调用就直接返回了,调用者不会立刻得到结果。被调用者会通过状态、通知或回调函数等方式返回结果。
网络IO模型
在阻塞与非阻塞、同步与异步的概念基础上,网络IO模型可以大致分为5类:阻塞IO、非阻塞IO、IO多路复用、信号驱动式IO、异步IO。阻塞IO和非阻塞IO已经在前面介绍过,下面主要看一下另外三种模型。
IO多路复用
和阻塞I/O所不同的是,IO多路复用可以用 select 系统调用同时阻塞多个I/O操作,而且可以同时对多个读操作或写操作的I/O函数进行检测,直到有数据可读或可写时,才调用真正的I/O读写操作(recvfrom),也就是说一个线程可以响应多个请求。
信号驱动IO
又称为事件驱动IO。首先开启套接字的信号驱动式IO功能,并且通过 sigaction 系统调用安装一个信号处理函数,该调用立即返回,进程没有被阻塞,继续工作;当数据准备好的时候,内核为该进程产生 SIGIO 的信号,随后可以在信号处理函数中调用 recvfrom 读取数据,并通知主循环数据已经准备好,或直接通知主循环让它来读取数据。
异步IO
在异步IO模型中,当用户线程收到通知时,数据已经被内核读取完毕,并放在了用户线程指定的缓冲区内,内核在IO完成后通知用户线程直接使用即可。
与多路复用模型的区别在于,当进程得到内核的通知时,异步IO模型中数据已经在用户空间了;而多路复用模型中,数据还在内核控件,需要应用进程去内核空间里面拷贝。
如果拿外卖做类比的话,多路复用模型相当于收到通知后到店自取,异步IO模型就是送餐上门。相对来说,异步IO是更加理想的IO模型。
Java7之后开始支持异步IO。相比于IO多路复用模型,异步IO并不十分常用,因为目前操作系统(尤其Linux)对异步IO的支持还不是特别好。高性能并发服务程序(比如Netty),一般都使用IO多路复用模型+多线程任务处理的架构。
我会持续更新关于物联网、云原生以及数字科技方面的文章,用简单的语言描述复杂的技术,也会偶尔发表一下对IT产业的看法,欢迎大家关注,谢谢。
- 上一篇: parseq-让java异步并发编程更简单
- 下一篇: Java:了解Java中的异步套接字通道
猜你喜欢
- 2024-11-27 多线程技术(同步异步,并发并行)守护线程(java垃圾回收机制)
- 2024-11-27 Java 爬虫遇上数据异步加载,试试这两种办法
- 2024-11-27 Java 17 多线程的同步和异步synchronized关键字
- 2024-11-27 java异步编程产生的原因
- 2024-11-27 Java:了解Java中的异步套接字通道
- 2024-11-27 parseq-让java异步并发编程更简单
- 2024-11-27 Java异步记录日志-2022新项目
- 2024-11-27 Java异步编程实战:基于JDK中的Future实现异步编程
- 2024-11-27 Java8异步编程就是拽的不行
- 2024-11-27 Java异步任务优化CompletionService
你 发表评论:
欢迎- 04-11Java面试“字符串三兄弟”String、StringBuilder、StringBuffer
- 04-11Java中你知道几种从字符串中找指定的字符的数量
- 04-11探秘Java面试中问的最多的String、StringBuffer、StringBuilder
- 04-11Python字符串详解与示例(python字符串的常见操作)
- 04-11java正则-取出指定字符串之间的内容
- 04-11String s1 = new String("abc");这句话创建了几个字符串对象?
- 04-11java判断字符串中是否包含某个字符
- 04-11关于java开发中正确的发牌逻辑编写规范
- 最近发表
-
- Java面试“字符串三兄弟”String、StringBuilder、StringBuffer
- Java中你知道几种从字符串中找指定的字符的数量
- 探秘Java面试中问的最多的String、StringBuffer、StringBuilder
- Python字符串详解与示例(python字符串的常见操作)
- java正则-取出指定字符串之间的内容
- String s1 = new String("abc");这句话创建了几个字符串对象?
- java判断字符串中是否包含某个字符
- 关于java开发中正确的发牌逻辑编写规范
- windows、linux如何后台运行jar(并且显示进程名)
- 腾讯大佬私人收藏,GitHub上最受欢迎的100个JAVA库,值得学习
- 标签列表
-
- nginx反向代理 (57)
- nginx日志 (56)
- nginx限制ip访问 (62)
- mac安装nginx (55)
- java和mysql (59)
- java中final (62)
- win10安装java (72)
- java启动参数 (64)
- java链表反转 (64)
- 字符串反转java (72)
- java逻辑运算符 (59)
- java 请求url (65)
- java信号量 (57)
- java定义枚举 (59)
- java字符串压缩 (56)
- java中的反射 (59)
- java 三维数组 (55)
- java插入排序 (68)
- java线程的状态 (62)
- java异步调用 (55)
- java中的异常处理 (62)
- java锁机制 (54)
- java静态内部类 (55)
- java怎么添加图片 (60)
- java 权限框架 (55)
本文暂时没有评论,来添加一个吧(●'◡'●)