从操作系统内核看Java非阻塞IO事件检测
非阻塞服务器模型最重要的一个特点是,在调用读取或写入接口后立即返回,而不会进入阻塞状态。在探讨单线程非阻塞IO模型前必须要先了解非阻塞情况下Socket事件的检测机制,因为对于非阻塞模式最重要的事情是检测哪些连接有感兴趣的事件发生,一般会有如下三种检测方式。
应用程序遍历socket检测
如图所示,当多个客户端向服务器请求时,服务器端会保存一个socket连接列表,应用层线程对socket列表进行轮询尝试读取或写入。对于读取操作,如果成功读取到若干数据则对读取到的数据进行处理,读取失败则下个循环再继续尝试;对于写入操作,先尝试将数据写入指定的某个socket,写入失败则下个循环再继续尝试。
这样看来,不管多少个socket连接都可以被一条线程管理起来,一条线程负责遍历这些socket列表,不断地尝试读取或写入数据,很好地利用了阻塞的时间,处理能力得到提升。但这种模型需要在应用程序中遍历所有的socket列表,同时需要处理数据的拼接,连接空闲时可能也会占用较多CPU资源,不适合实际使用。对此改进是使用事件驱动的非阻塞方式。
内核遍历socket的事件检测
这种方式将socket的遍历工作交给了操作系统内核,对socket遍历的结果组织成一系列的事件列表并返回应用层处理。对于应用层,他们需要处理的对象就是这些事件,这就是其中一种事件驱动的非阻塞方式的实现。
如图所示,服务器端有多个客户端连接,应用层向内核请求读写事件列表。内核遍历所有socket并生成对应的可读列表readList和可写列表writeList,readList标明了每个socket是否可读,例如socket1的值为1,表示可读,socket2的值为0,表示不可读。writeList则标明了每个socket是否可写。应用层遍历读写事件列表readList和writeList,做相应的读写操作。
内核遍历socket的方式已经不用在应用层对所有socket进行遍历,将遍历工作下移到内核层,这种方式有助于提高检测效率。但是它需要将所有连接的可读事件列表和可写事件列表传到应用层,假如socket连接数量大起来的话,列表从内核复制到应用层也是不小的开销。另外,当活跃连接较少时,内核与应用层之间存在很多无效的数据拷贝,因为它是将活跃和不活跃的连接状态都拷贝到应用层了。
内核基于回调的事件检测
通过遍历的方式检测socket是否可读可写是一种效率比较低的方式,不管是在应用层遍历还是在内核遍历。所以需要另外一种机制来优化遍历的方式,那就是回调函数。内核中socket都对应一个回调函数,当客户端往socket发送数据时,内核从网卡接收数据后就会调回调函数将此socket作为可读事件加入到事件列表中。应用层获取此事件列表即可得到所有感兴趣的事件。
如图所示,服务器端有多个客户端socket连接,首先应用层告诉内核每个socket感兴趣的事件;接着当客户端发送数据过来时,对应会有一个回调函数,内核从网卡复制数据成功后即调回调函数将socket1作为可读事件event1加入到事件列表,同样地,内核发现网卡可写时就将socket2作为可写事件event2添加到事件列表中;最后,应用层向内核请求读写事件列表,内核将包含了event1和event2的事件列表返回应用层,应用层通过遍历事件列表得知socket1有数据待读取,于是进行读操作,而socket2则可以写入数据。
这种方式由操作系统内核维护客户端的所有连接并通过回调函数不断更新可读可写事件列表,而应用层线程只要遍历这些事件列表即可知道可读取或可写入的连接,进而对这些连接进行读写操作。极大提高了检测效率,自然处理能力也更强。
上面介绍了三种非阻塞的事件检测机制,对于Java来说,非阻塞IO的实现完全是基于操作系统内核的非阻塞IO,它将操作系统的非阻塞IO的差异屏蔽了并提供统一的API,让我们不必关心操作系统。JDK会帮我们选择非阻塞IO的实现方式,例如对于Linux系统,在支持epoll的情况下JDK会优先选择用epoll实现Java的非阻塞IO。这种非阻塞方式的事件检测机制就是效率最高的“内核基于回调的事件检测”。
从操作系统内核看Java非阻塞IO事件检测的更多相关文章
- Java网络编程和NIO详解5:Java 非阻塞 IO 和异步 IO
Java网络编程和NIO详解5:Java 非阻塞 IO 和异步 IO Java 非阻塞 IO 和异步 IO 转自https://www.javadoop.com/post/nio-and-aio 本系 ...
- java非阻塞IO(NIO)流程
单线程 多线程(Netty/Mina)
- 谈谈对不同I/O模型的理解 (阻塞/非阻塞IO,同步/异步IO)
一.关于I/O模型的问题 最近通过对ucore操作系统的学习,让我打开了操作系统内核这一黑盒子,与之前所学知识结合起来,解答了长久以来困扰我的关于I/O的一些问题. 1. 为什么redis能以单工作线 ...
- 网络IO模型:同步IO和异步IO,阻塞IO和非阻塞IO
同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到底有什么区别?这个问题其实不同的人给出 ...
- 转 网络IO模型:同步IO和异步IO,阻塞IO和非阻塞IO
此文章为转载,如有侵权,请联系本人.转载出处,http://blog.chinaunix.net/uid-28458801-id-4464639.html 同步(synchronous) IO和异步( ...
- linux基础编程:IO模型:阻塞/非阻塞/IO复用 同步/异步 Select/Epoll/AIO(转载)
IO概念 Linux的内核将所有外部设备都可以看做一个文件来操作.那么我们对与外部设备的操作都可以看做对文件进行操作.我们对一个文件的读写,都通过调用内核提供的系统调用:内核给我们返回一个file ...
- 阻塞IO、非阻塞IO的区别
1.类与类之间的关系:依赖,实现,泛化(继承),关联,组合,聚合. 1)依赖(虚线):一个类是 另一个类的函数参数 或者 函数返回值. 2)实现(实线加小圆):对纯虚函数类(抽象类)的实现. 3)继承 ...
- 5种IO模型、阻塞IO和非阻塞IO、同步IO和异步IO
POSIX 同步IO.异步IO.阻塞IO.非阻塞IO,这几个词常见于各种各样的与网络相关的文章之中,往往不同上下文中它们的意思是不一样的,以致于我在很长一段时间对此感到困惑,所以想写一篇文章整理一下. ...
- 非阻塞IO模式原理
与阻塞模式对应的另一种模式叫非阻塞IO模式,在整个通信过程中读和写操作不会阻塞,当前处理线程不存在阻塞情况.从A机器到B机器它的通信过程是:A机器一条线程将通道设置为写事件后往下执行,而另外一条线程遍 ...
随机推荐
- [WC 2011]Xor
Description Input 第一行包含两个整数N和 M, 表示该无向图中点的数目与边的数目. 接下来M 行描述 M 条边,每行三个整数Si,Ti ,Di,表示 Si 与Ti之间存在 一条权值为 ...
- [HNOI 2011]XOR和路径
Description 给定一个无向连通图,其节点编号为 1 到 N,其边的权值为非负整数.试求出一条从 1 号节点到 N 号节点的路径,使得该路径上经过的边的权值的“XOR 和”最大.该路径可以重复 ...
- [HNOI 2009]最小圈
Description 考虑带权的有向图$G=(V,E)$以及$w:E\rightarrow R$,每条边$e=(i,j)(i\neq j,i\in V,j\in V)$的权值定义为$w_{i,j}$ ...
- 【bzoj4571 scoi2016】美味
题目描述 一家餐厅有 n 道菜,编号 1...n ,大家对第 i 道菜的评价值为 ai(1<=i<=n).有 m 位顾客,第 i 位顾客的期望值为 bi,而他的偏好值为 xi .因此,第 ...
- poj 2774 最长公共子串 后缀数组
Long Long Message Time Limit: 4000MS Memory Limit: 131072K Total Submissions: 25752 Accepted: 10 ...
- JSP 基本语法
1 JSP 的由来 servlet产生后,存在很大的问题,为了表现页面的效果,需要输出大量的HTML 语句,表现为一个个字符串,不仅利于开发,也不利于后期的维护,由此产生了JSP.主要用于将Servl ...
- SpringCloud学习之SpringCloudStream&集成kafka
一.关于Spring-Cloud-Stream Spring Cloud Stream本质上就是整合了Spring Boot和Spring Integration,实现了一套轻量级的消息驱动的微服务框 ...
- python绘制散点图,柱状图和折线图
示例:散点图 最常见的散点图之一是x-y散点图.下面的代码会大致告诉你一个matplotlib是如何工作的,你会看到如何一点点建立起一个散点图. 我们正在使用点的x和y位置的一些构成数据.运行下面的代 ...
- 【Tensorflow系列】使用Inception_resnet_v2训练自己的数据集并用Tensorboard监控
[写在前面] 用Tensorflow(TF)已实现好的卷积神经网络(CNN)模型来训练自己的数据集,验证目前较成熟模型在不同数据集上的准确度,如Inception_V3, VGG16,Inceptio ...
- Spring 自带的定时任务Scheduled
1.注解@Scheduled 可以作为一个触发源添加到一个方法中,例如,以下的方法将以一个固定延迟时间5秒钟调用一次执行,这个周期是以上一个调用任务的完成时间为基准,在上一个任务完成之后,5s后再次执 ...