从上篇文章的介绍(见:http://pengpeng.iteye.com/blog/875520)我们知道linux内核根据TCP/IP网络模型,给我们隐藏了传输层以下的网络传输细节,我们的网络应用程序只需要针对socket编程即可。这篇我们立足网络数据包的I/O。谈谈linux的一些I/O知识,以及Java的NIO.
1. 基础知识
我们知道Linux的内核将所有外部设备都可以看做一个文件来操作。那么我们对与外部设备的操作都可以看做对文件进行操作。我们对一个文件的读写,都通过调用内核提供的系统调用;内核给我们返回一个file descriptor(简称:fd,文件描述符);我们通过 ls -l /proc/${pid}/fd/ 可以看到进程${pid}占用的所有描述符,或者lsof -p ${pid}; 而对一个socket的读写也会有相应的描述符,称为socketfd(socket描述符);描述符就是一个数字,指向内核中一个结构体(文件路径,数据区,等一些属性) ; 那么我们的应用程序对文件的读写就通过对描述符的读写完成。
系统调用是如何完成一个I/O操作的呢? linux将内存分为内核区,用户区; linux内核给我们管理所有的硬件资源,应用程序通过调用系统调用和内核交互,达到使用硬件资源的目的; 应用程序通过系统调用read发起一个读操作;这时候内核创建一个文件描述符,并通过驱动程序向硬件发送读指令,并将读的的数据放在这个描述符对应结构体的缓存区。但这个结构体是在内核内存区的。需要将这个数据读到用户区。这样完成了一次读操作;
但是大家都知道I/O设备相比cpu的速度是极慢的。linux提供的read系统调用,也是一个阻塞函数。这样我们的应用进程在发起read系统调用时,就必须阻塞,就进程被挂起而等待文件描述符的读就绪;
这里,我们先了解一下,什么是文件描述符读就绪,什么是写就绪?
读就绪:就是这个文件描述符的接收缓冲区中的数据字节数大于等于套接字接收缓冲区低水位标记的当前大小;
写就绪
:该描述符发送缓冲区的可用空间字节数大于等于描述符发送缓冲区低水位标记的当前大小。(如果是socket fd,说明上一个数据已经发送完成)。
接收低水位标记和发送低水位标记:由应用程序指定,比如应用程序指定接收低水位为64个字节。那么接收缓冲区有64个字节,才算fd读就绪;
2.各种I/O模型比较
有没有办法能让我们在I/O时,不让我们的应用程序阻塞;从上边的分析我们知道向内核发起一个I/O操作,要经过等待fd就绪+内核数据到用户数据区复制,完成一次I/O;
Linux POSIX是这样定义同步I/O 和 异步I/O的:
- 同步I/O操作(synchronous I/O operation):导致请求进程阻塞,直到I/O操作完成。
- 异步I/O操作(asynchronous I/O operation): 不导致请求进程阻塞。
根据上述定义,我们的前四种模型------阻塞式I/O模型,非阻塞式I/O模型、I/O多路复用模型和信号驱动式I/O模型,因为其中真正的I/O操作将阻塞进程。只有异步I/O模型与POSIX定义的异步I/O相匹配;
图: Linux 提供的所有I/O模型
阻塞式
:最普通的I/O模型;原生的read/write系统调用,默认是阻塞模式;导致进程阻塞;
非阻塞
:这种方式通过指定系统调用read/write的参数为非阻塞,告知内核fd没就绪时,不阻塞进程,而是返回一个错误码,应用进程死循环轮询,直到fd就绪;
异步非阻塞(I/O复用):
linux提供select/poll,进程通过将一个或多个fd传递给select或poll系统调用,阻塞在select;这样select/poll可以帮我们侦测许多fd是否就绪;但是select/poll是顺序扫描fd是否就绪,而且支持的fd数量有限。linux还提供了一个epoll系统调用,epoll是基于事件驱动方式,而不是顺序扫描,当有fd就绪时,立即回调函数rollback;
异步非阻塞(信号驱动式I/O):
内核在描述符就绪时发送SIGIO信号通知进程,进程通过信号处理函数接收数据;
异步I/O(AIO):
告知内核某个操作,并让内核在整个操作(包括将数据复制到我们的进程缓冲区)完成后通知我们。这种模型和信号驱动式I/O模型区别在于:信号驱动式I/O由内核通知我们何时可以启动一个I/O操作,而异步I/O模型是内核通知我们I/O操作何时完成。(此模型linux 2.6 内核推出)
3. java的NIO(new i/o)
我们知道jdk 1.4版本里推出了java nio .此后java的很多网络应用都重写了底层I/O模块,大大提高并发性能;包括tomcat, jetty等;
java nio api 里通过将许多fd扔给一个Selector去检测fd是否就绪;
那么java 的nio使用的是那种I/O模型呢?
通过查看jvm代码:(下载地址:http://download.java.net/jdk6/source/
)
可见jvm的NIO使用的是linux 系统调用epoll模型;
4. java何时支持真正的AIO模型呢?
JSR 203(http://jcp.org/en/jsr/detail?id=203
) 在java SE 7.0中会完成JSR203.估计不久以后就可以普及了。asynchronous I/O对于java 绝对影响巨大,java写的网络服务器能够支持更大并发请求了。到时肯定大多网络服务器的I/O底层代码都会修改。就像当时Linux 2.6 支持AIO模型,很多数据库oracle,DB2都发布新版本。
分享到:
相关推荐
ysoserial是一个用于生成利用不安全的Java对象反序列化的有效负载的概念验证工具。它包含一系列在常见Java库中发现的"gadget chains",可以在特定条件下利用执行不安全的反序列化操作的Java应用程序。ysoserial项目最初在2015年AppSecCali会议上提出,包含针对Apache Commons Collections(3.x和4.x版本)、Spring Beans/Core(4.x版本)和Groovy(2.3.x版本)的利用链
1、嵌入式物联网单片机项目开发例程,简单、方便、好用,节省开发时间。 2、代码使用IAR软件开发,当前在CC2530上运行,如果是其他型号芯片,请自行移植。 3、软件下载时,请注意接上硬件,并确认烧录器连接正常。 4、有偿指导v:wulianjishu666; 5、如果接入其他传感器,请查看账号发布的其他资料。 6、单片机与模块的接线,在代码当中均有定义,请自行对照。 7、若硬件有差异,请根据自身情况调整代码,程序仅供参考学习。 8、代码有注释说明,请耐心阅读。 9、例程具有一定专业性,非专业人士请谨慎操作。
YOLO系列算法目标检测数据集,包含标签,可以直接训练模型和验证测试,数据集已经划分好,包含数据集配置文件data.yaml,适用yolov5,yolov8,yolov9,yolov7,yolov10,yolo11算法; 包含两种标签格:yolo格式(txt文件)和voc格式(xml文件),分别保存在两个文件夹中,文件名末尾是部分类别名称; yolo格式:<class> <x_center> <y_center> <width> <height>, 其中: <class> 是目标的类别索引(从0开始)。 <x_center> 和 <y_center> 是目标框中心点的x和y坐标,这些坐标是相对于图像宽度和高度的比例值,范围在0到1之间。 <width> 和 <height> 是目标框的宽度和高度,也是相对于图像宽度和高度的比例值; 【注】可以下拉页面,在资源详情处查看标签具体内容;
**Oracle 10g DBA学习手册:安装Oracle和构建数据库** **目的:** 本章节旨在指导您完成Oracle数据库软件的安装和数据库的创建。您将通过Oracle Universal Installer (OUI)了解软件安装过程,并学习如何利用Database Configuration Assistant (DBCA)创建附加数据库。 **主题概览:** 1. 利用Oracle Universal Installer (OUI)安装软件 2. 利用Database Configuration Assistant (DBCA)创建数据库 **第2章:Oracle软件的安装与数据库构建** **Oracle Universal Installer (OUI)的运用:** Oracle Universal Installer (OUI)是一个图形用户界面(GUI)工具,它允许您查看、安装和卸载机器上的Oracle软件。通过OUI,您可以轻松地管理Oracle软件的安装和维护。 **安装步骤:** 以下是使用OUI安装Oracle软件并创建数据库的具体步骤:
消防验收过程服务--现场记录表.doc
数据库管理\09-10年第1学期数据库期末考试试卷A(改卷参考).doc。内容来源于网络分享,如有侵权请联系我删除。另外如果没有积分的同学需要下载,请私信我。
YOLO系列算法目标检测数据集,包含标签,可以直接训练模型和验证测试,数据集已经划分好,包含数据集配置文件data.yaml,适用yolov5,yolov8,yolov9,yolov7,yolov10,yolo11算法; 包含两种标签格:yolo格式(txt文件)和voc格式(xml文件),分别保存在两个文件夹中,文件名末尾是部分类别名称; yolo格式:<class> <x_center> <y_center> <width> <height>, 其中: <class> 是目标的类别索引(从0开始)。 <x_center> 和 <y_center> 是目标框中心点的x和y坐标,这些坐标是相对于图像宽度和高度的比例值,范围在0到1之间。 <width> 和 <height> 是目标框的宽度和高度,也是相对于图像宽度和高度的比例值; 【注】可以下拉页面,在资源详情处查看标签具体内容;
职业暴露后的处理流程.docx
Java Web开发短消息系统
项目包含完整前后端源码和数据库文件 环境说明: 开发语言:Java 框架:ssm,mybatis JDK版本:JDK1.8 数据库:mysql 5.7 数据库工具:Navicat11 开发软件:eclipse/idea Maven包:Maven3.3 服务器:tomcat7
这是一款可以配置过滤目录及过滤的文件后缀的工具,并且支持多个项目同时输出导出,并过滤指定不需要导出的目录及文件后缀。 导出后将会保留原有的路径,并在新的文件夹中体现。
Matlab领域上传的视频均有对应的完整代码,皆可运行,亲测可用,适合小白; 1、代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作
YOLO算法-挖掘机与火焰数据集-7735张图像带标签-挖掘机.zip
操作系统实验 Ucore lab5
IMG_5950.jpg
竞选报价评分表.docx
java系统,mysql、springboot等框架
1、嵌入式物联网单片机项目开发例程,简单、方便、好用,节省开发时间。 2、代码使用IAR软件开发,当前在CC2530上运行,如果是其他型号芯片,请自行移植。 3、软件下载时,请注意接上硬件,并确认烧录器连接正常。 4、有偿指导v:wulianjishu666; 5、如果接入其他传感器,请查看账号发布的其他资料。 6、单片机与模块的接线,在代码当中均有定义,请自行对照。 7、若硬件有差异,请根据自身情况调整代码,程序仅供参考学习。 8、代码有注释说明,请耐心阅读。 9、例程具有一定专业性,非专业人士请谨慎操作。
YOLO系列算法目标检测数据集,包含标签,可以直接训练模型和验证测试,数据集已经划分好,包含数据集配置文件data.yaml,适用yolov5,yolov8,yolov9,yolov7,yolov10,yolo11算法; 包含两种标签格:yolo格式(txt文件)和voc格式(xml文件),分别保存在两个文件夹中,文件名末尾是部分类别名称; yolo格式:<class> <x_center> <y_center> <width> <height>, 其中: <class> 是目标的类别索引(从0开始)。 <x_center> 和 <y_center> 是目标框中心点的x和y坐标,这些坐标是相对于图像宽度和高度的比例值,范围在0到1之间。 <width> 和 <height> 是目标框的宽度和高度,也是相对于图像宽度和高度的比例值; 【注】可以下拉页面,在资源详情处查看标签具体内容;
内容概要:本文详细讲解了搜索引擎的基础原理,特别是索引机制、优化 like 前缀模糊查询的方法、建立索引的标准以及针对中文的分词处理。文章进一步深入探讨了Lucene,包括它的使用场景、特性、框架结构、Maven引入方法,尤其是Analyzer及其TokenStream的实现细节,以及自定义Analyzer的具体步骤和示例代码。 适合人群:数据库管理员、后端开发者以及希望深入了解搜索引擎底层实现的技术人员。 使用场景及目标:适用于那些需要优化数据库查询性能、实施或改进搜索引擎技术的场景。主要目标在于提高数据库的访问效率,实现高效的数据检索。 阅读建议:由于文章涉及大量的技术术语和实现细节,建议在阅读过程中对照实际开发项目,结合示例代码进行实践操作,有助于更好地理解和吸收知识点。