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 模型(终)的更多相关文章

  1. [转载] Linux五种IO模型

      转载:http://blog.csdn.net/jay900323/article/details/18141217     Linux五种IO模型性能分析   目录(?)[-] 概念理解 Lin ...

  2. Windows五种IO模型性能分析和Linux五种IO模型性能分析

    Windows五种IO模型性能分析和Linux五种IO模型性能分析 http://blog.csdn.net/jay900323/article/details/18141217 http://blo ...

  3. (转载) Linux五种IO模型

    转载:http://blog.csdn.net/jay900323/article/details/18141217     Linux五种IO模型及分析   目录(?)[-] 概念理解 Linux下 ...

  4. Linux 的 Socket IO 模型

    前言 之前有看到用很幽默的方式讲解Windows的socket IO模型,借用这个故事,讲解下linux的socket IO模型: 老陈有一个在外地工作的女儿,不能经常回来,老陈和她通过信件联系. 他 ...

  5. 网络通信 --> Linux 五种IO模型

    Linux 五种IO模型 聊聊Linux 五种IO模型

  6. Linux五种IO模型(同步 阻塞概念)

    Linux五种IO模型 同步和异步 这两个概念与消息的通知机制有关. 同步 所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回.比如,调用readfrom系统调用时,必须等待IO操 ...

  7. linux下的IO模型---学习笔记

    1.linux文件系统和缓存 文件系统接口 文件系统-一种把数据组织成文件和目录的存储方式,提供了基于文件的存取接口,并通过文件权限控制访问. 存储层次 文件系统缓存 主存(通常时DRAM)的一块区域 ...

  8. 深入理解JAVA I/O系列六:Linux中的IO模型

    IO模型 linux系统IO分为内核准备数据和将数据从内核拷贝到用户空间两个阶段. 这张图大致描述了数据从外部磁盘向运行中程序的内存中移动的过程. 用户空间.内核空间 现在操作系统都是采用虚拟存储器, ...

  9. Linux五种IO模型性能分析

    1. 概念理解 在进行网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式: 同步:       所谓同步,就是在发出一个功能调用时, ...

随机推荐

  1. 多图文,详细介绍mysql各个集群方案

    目录 多图文,详细介绍mysql各个集群方案 一,mysql原厂出品 二,mysql第三方优化 三,依托硬件配合 四,其它 多图文,详细介绍mysql各个集群方案 集群的好处 高可用性:故障检测及迁移 ...

  2. 【原创】(四)Linux进程调度-组调度及带宽控制

    背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...

  3. Flutter的盒子约束

    由Expanded widget引发的思考 设计稿如下 布局widget分解 很常见的一种布局方式:Column的子widget中包含ListView @override Widget build(B ...

  4. 利用Python爬取OPGG上英雄联盟英雄胜率及选取率信息

    一.分析网站内容 本次爬取网站为opgg,网址为:” http://www.op.gg/champion/statistics” 由网站界面可以看出,右侧有英雄的详细信息,以Garen为例,胜率为53 ...

  5. Python+Android进行TensorFlow开发

    Tensorflow是Google开源的一套机器学习框架,支持GPU.CPU.Android等多种计算平台.本文将介绍在Tensorflow在Android上的使用. Android使用Tensorf ...

  6. 关于动态路由中路由之间的跳转(页面a跳转到页面b)

    由addRouters方法获取到后台的动态路由,要实现路由之间的跳转,不可直接用path: '***',而是将动态路由存储到vuex中,再从vuex中取得,如:this.$store.menu.nav ...

  7. 使用Github Packages功能上传nuget包到Github

    前几天微软收购npm的新闻对于软粉来收很是振奋.微软收购npm很可能是为了加强Github Packages.目前Github,Typescript,VSCode,npm这些开源社区的重磅工具全部都在 ...

  8. 在5G+AI+Cl 拉动互联网走向物联网

    大家好我是浅笑若风,今天在这里和大家聊聊的是:5G+AI+CL拉动互联网走向物联网 在虫洞时空里我们早已能遇见到世界的尽头会是什么样子,微服务,微生活的迅速发展的时代.我们在虚拟的多次元世界购物.交易 ...

  9. Fluent算例精选|02瞬态滑移网格分析叶轮机械内部流动

    本算例使用的软件:fluent.icem 通过学习本算例您将获得? 1.学会周期区域创建 2.学会瞬态求解器及滑移网格边界条件设置 3.学会周期面.滑移面设置 4.学会如何监测压力脉动(声学仿真) 5 ...

  10. ngzorro draw 第一次打开 ERROR TypeError: Cannot read property 'overlayElement' of undefined

    at NzDrawerComponent.push../node_modules/ng-zorro-antd/fesm5/ng-zorro-antd.js.NzDrawerComponent.trap ...