从 Linux 操作系统谈谈 IO 模型(终)
Linux 为什么要区分内核空间与用户空间?
Linux 操作系统的 IO 模型有哪几种?有啥区别?
常说的阻塞现象,到底是咋回事?
网络编程研发时,那块到底耗时最多,代码是否还有优化空间?
前几期的分享,我们站在编码视角去聊 Java IO,旨在理解与编码,本次从 Linux 操作系统层面了解一下 IO 模型,这样方能做到知其然,知其所以然。
01. 内核空间、用户空间
万事万物我们看到的皆是表象,操作系统也不例外。我们经常打交道的用户界面,是操作系统的外在表象,内核才是操作系统的内在核心。
内核,可以访问受保护的内存空间,拥有访问底层硬件设备的所有权限(比如读写磁盘文件,分配回收内存,从网络接口读写数据等等)。
为了内核的安全,操作系统将虚拟空间划分为内核空间(内核代码运行的地方)和用户空间(用户程序代码运行的地方)。内核空间和用户空间是隔离的,这样即使用户的程序崩溃了,内核也不受影响。
另外,用户程序不能直接操作内核,需要通过系统调用来与内核进行通信(应用程序通过内核提供的接口来完成访问)。
02. Socket 通信流程
Socket 通信流程应该不再陌生,本次分享着重剖析图中圈住的部分。
站在服务端的视角,对于一次 Socket 的数据读取操作流程,如图示意,网络数据到达网卡,数据先被拷贝到内核缓冲区中,然后从内核缓冲区拷贝到进程用户空间。
站在服务端的视角,当一个读操作发生时,稍微再细化一下,其实会经历两个阶段。
第一阶段:等待数据准备。
例如:recv() 等待数据,需要等待网络上的数据分组到达,然后被复制到内核的缓冲区。
第二阶段:将数据从内核缓冲区拷贝到用户空间。
例如:recv() 接收连接发送的数据后,需要把数据复制到内核缓冲区,再从内核缓冲区复制到进程用户空间。
一定记住这两个阶段,也正因为存在这两个阶段,Linux系统升级迭代中出现了五种网络 IO 模型。
03. Linux 网络 IO 模型
(一)阻塞 IO 模型 - Blocking IO
图解:当应用进程调用了 recv() 这个系统调用,内核就开始了 IO 的第一个阶段:准备数据。这个过程需要等待,也就是说数据被拷贝到操作系统内核的缓冲区中是需要一个过程的。而在用户进程这边,整个进程会被阻塞。当内核一直等到数据准备好了,它就会将数据从内核中拷贝到用户内存,然后内核返回结果,用户进程才解除阻塞的状态。
特点:在 IO 执行的两个阶段都被阻塞了。
场景:阻塞 Socket、Java BIO。适用并发较小的网络应用,并发较大的不适用,因为一个请求 IO 阻塞进程,就要为每个请求分配一个进程(线程)来响应,开销大。
(二)非阻塞 I/O 模型 - Non-Blocking IO
图解:当用户进程发出 recv() 操作时,如果内核中的数据还没有准备好,那么它并不会阻塞用户进程,而是立刻返回一个错误码。一旦内核中的数据准备好了,并且又再次收到了用户进程的系统调用,那么它马上就将数据拷贝到了用户内存,然后返回。
特点:用户进程需要不断的主动询问内核数据好了没有,进程轮询调用,消耗 CPU 资源。
场景:SOCKET 设置 NON BLOCKING 属性。支持并发量小,不用及时响应的网络应用。
(三)I/O多路复用 - IO multiplexing
在 Linux 内核代码迭代过程中,依次支持了 SELECT、POLL、EPOLL 三种多路复用的网络 I/O 模型。
IO 多路复用的的基本原理是指单个线程就可以同时处理多个网络连接。 具体实现是 SELECT、POLL、EPOLL这些函数,会不断的轮询所负责的所有 socket,当某个 socket 有数据到达了,就通知用户进程。
图解:以 select 为例,当用户进程调用了 select,那么整个进程会被阻塞,而此时,内核会监视所有 select 负责的 socket,当任何一个 socket 中的数据准备好了,select 就会返回。这个时候用户进程再调用 recv 操作,将数据从内核拷贝到用户进程。
特点:IO 多路复用是阻塞在 select,poll,epoll 这样的系统调用之上,而没有阻塞在真正的I/O系统调用(如recv());专一进程解决多个进程 IO 的阻塞问题,性能好,Reactor模式。
场景:Java NIO,Nginx。适用高并发服务应用开发,一个进程/线程响应多个请求。
(四)信号驱动 I/O - Signal driven IO
我们也可以用信号,让内核在描述字就绪时发送 SIGIO 信号通知我们,称这种模型为信号驱动I/O(signal-driven I/O)。
应用进程使用 sigaction 系统调用,预先告知内核,向内核注册这样一个函数,内核立即返回,应用进程可以继续执行,也就是说等待数据阶段应用进程是非阻塞的。内核在数据到达时向应用进程发送 SIGIO 信号,应用进程收到之后在信号处理程序中调用 recv() 将数据从内核复制到应用进程中。
(五)异步 I/O 模型 - Asynchronous IO
图解:应用进程执行 aio_read() 系统调用会立即返回,应用进程可以继续执行,不会被阻塞,内核会在所有操作完成之后向应用进程发送信号。
特点:不阻塞,一步到位。
场景: Java 7 AIO、高性能服务器,高性能高并发。
异步 IO 模型,要求等待数据和数据拷贝操作的两个处理阶段上都不能等待(blocking),内核自行去准备好数据并将数据从内核缓冲区中复制到应用进程的缓冲区,再通知应用进程读操作完成了,然后应用进程再去处理。
遗憾的是,Linux 的网络 IO 模型中是不存在异步 IO 的,Linux 的网络 IO 处理的第二阶段总是阻塞等待数据 copy 完成的。
04. Linux 网络 IO 模型比较
上图已经把 Linux 中的 IO 模型归档的很到位,还是稍微总结一下。前四种 IO 模型都是同步 IO 模型,主要区别在于第一阶段的处理不同,第二阶段的处理是相同的,都是在数据从内核复制到用户空间时,进程阻塞于 recv() 调用。而异步 IO 模型的处理都是非阻塞的,用户进程将整个 IO 操作交由内核去完成,内核完成后会发送通知。
好了,今天就扯这么多,希望大家能够喜欢。
从 Linux 操作系统谈谈 IO 模型(终)的更多相关文章
- [转载] Linux五种IO模型
转载:http://blog.csdn.net/jay900323/article/details/18141217 Linux五种IO模型性能分析 目录(?)[-] 概念理解 Lin ...
- Windows五种IO模型性能分析和Linux五种IO模型性能分析
Windows五种IO模型性能分析和Linux五种IO模型性能分析 http://blog.csdn.net/jay900323/article/details/18141217 http://blo ...
- (转载) Linux五种IO模型
转载:http://blog.csdn.net/jay900323/article/details/18141217 Linux五种IO模型及分析 目录(?)[-] 概念理解 Linux下 ...
- Linux 的 Socket IO 模型
前言 之前有看到用很幽默的方式讲解Windows的socket IO模型,借用这个故事,讲解下linux的socket IO模型: 老陈有一个在外地工作的女儿,不能经常回来,老陈和她通过信件联系. 他 ...
- 网络通信 --> Linux 五种IO模型
Linux 五种IO模型 聊聊Linux 五种IO模型
- Linux五种IO模型(同步 阻塞概念)
Linux五种IO模型 同步和异步 这两个概念与消息的通知机制有关. 同步 所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回.比如,调用readfrom系统调用时,必须等待IO操 ...
- linux下的IO模型---学习笔记
1.linux文件系统和缓存 文件系统接口 文件系统-一种把数据组织成文件和目录的存储方式,提供了基于文件的存取接口,并通过文件权限控制访问. 存储层次 文件系统缓存 主存(通常时DRAM)的一块区域 ...
- 深入理解JAVA I/O系列六:Linux中的IO模型
IO模型 linux系统IO分为内核准备数据和将数据从内核拷贝到用户空间两个阶段. 这张图大致描述了数据从外部磁盘向运行中程序的内存中移动的过程. 用户空间.内核空间 现在操作系统都是采用虚拟存储器, ...
- Linux五种IO模型性能分析
1. 概念理解 在进行网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式: 同步: 所谓同步,就是在发出一个功能调用时, ...
随机推荐
- intel硬件视频加速介绍
目录 硬件视频加速技术 intel 硬件加速技术 intel 的开源媒体栈 VA-API 安装 样例 Intel Quick Sync(QSV) API支持情况 vaapi/mfx比较 安装 样例 硬 ...
- libra共识算法分析
核心算法说明 基于chained实现,整体上是当前轮推动下一轮共识继续下去, 如此来持续运转下去, 数据有效性证明基于(QC)实现 leader广播proposal消息{round, qc, p ...
- 看完这篇 HTTPS,和面试官扯皮就没问题了
下面我们来一起学习一下 HTTPS ,首先问你一个问题,为什么有了 HTTP 之后,还需要有 HTTPS ?我突然有个想法,为什么我们面试的时候需要回答标准答案呢?为什么我们不说出我们自己的想法和见解 ...
- 我要打十个!详解建造者模式(builder pattern)
前言 "我要打十个",其实是我要打十个野怪! 这十个野怪呢,它们有不同的技能.装备和武器,长得也不一样.这里野怪是一个蛮复杂的对象,由各个不同的部分组成(技能.装备.武器等),不同 ...
- 【题解】NOIP 2015 子串
淦!这题我做了三个月啊 题目描述 有两个仅包含小写英文字母的字符串 \(A\) 和 \(B\). 现在要从字符串 \(A\) 中取出 \(k\) 个互不重叠的非空子串,然后把这 \(k\) 个子串按照 ...
- iviewadmin url 加入 Router base #viewDesignAdmin
router/index.js const router = new Router({ routes, base: '/viewDesignAdmin/', mode: 'history' ...
- 创建 VuePress + GithubPages + TravisCI 在线文档
目录 最终效果 思路 总体 过程 用到的东西 相关 创建Github仓库 创建Github仓库 SSH密钥链接Github 生成SSH密钥 Github添加SSH密钥 测试SSH密钥 配置VuePre ...
- 如何区分前端BUG和后台BUG?
测试工程师不只是负责发现问题,除了发现问题这种基本功外,定位问题,提出解决方案,提出预防方案也是要掌握的技能.这里先说定位问题的要求,定位问题要向深入,前提当然是对功能.产品的流程.开发方案.开发人员 ...
- 040.集群网络-CNI网络模型
一 CNM网络模型 1.1 网络模型 生产环境中,跨主机容器间的网络互通已经成为基本要求,更高的要求包括容器固定IP地址.一个容器多个IP地址.多个子网隔离.ACL控制策略.与SDN集成等.目前主流的 ...
- git 使用和一些错误
一.简单使用 Git是目前世界上最先进的分布式版本控制系统,用于自动记录每次文件的改动,但是和所有版本控制系统一样,只能跟踪文本文件的改动,比如TXT文件,网页,所有的程序代码等,而图片.视频这些二进 ...