异步io

BIO、NIO、AIO模型分析

耗尽温柔 提交于 2020-01-22 15:21:10
什么是 I/O 在计算机系统中I/O就是输入(Input)和输出(Output)的意思,针对不同的操作对象,可以划分为磁盘I/O模型,网络I/O模型,内存映射I/O, Direct I/O、数据库I/O等,常见的I/O有磁盘I/O和网络I/O。 什么是IO的Block呢?考虑下面两种情况: 用系统调用read从socket里读取一段数据 用系统调用read从一个磁盘文件读取一段数据到内存 对于第一种情况,算作Block,因为Linux无法知道网络上对方是否会发数据。如果没数据发过来,对于调用read的程序来说,就只能“等”。对于第二种情况,不算做Block。 一个解释是,所谓“Block”是指操作系统可以预见这个Block会发生才会主动Block。例如当读取TCP连接的数据时,如果发现Socket buffer里没有数据就可以确定定对方还没有发过来,于是Block;而对于普通磁盘文件的读写,也许磁盘运作期间会抖动,会短暂暂停,但是操作系统无法预见这种情况,只能视作不会Block,照样执行。我们讨论的BIO、NIO和AIO都是针对网络I/O模型。 进程中的IO调用步骤大致可以分为以下四步: 进程向操作系统请求数据 ; 操作系统把外部数据加载到内核的缓冲区中; 操作系统把内核的缓冲区拷贝到进程的缓冲区 ; 进程获得数据完成自己的功能 ; 当操作系统在把外部数据放到进程缓冲区的这段时间

第十五章 内存映射和DMA

拜拜、爱过 提交于 2020-01-20 03:03:29
1、mmap设备操作 映射一个设备意味着将用户空间的一段内存与设备内存关联起来。无论何时当程序在分配的地址范围内读写时,实际上访问的就是设备。不是所有的设备都能进行mmap抽象。比如像串口和其他面向流的设备就不能。mmap的另一个限制是:必须以PAGE_SIZE为单位进行映射。 mmap方法是file_operation结构的一部分,并且执行mmap系统调用时将调用该方法。为了执行mmap,驱动程序只需要为该地址范围建立合适的页表,并将vma->vm_ops替换为一系列的新操作即可。 有两种建立页表的方法:使用remap_pfn_range函数一次全部建立,或者通过nopage方法每次建立一个页。 2、执行直接IO访问 如果需要传递的数据量非常大,直接进行数据传输,而不需要额外的从内核空间拷贝数据操作的参与,这将会大大提高速度。使用直接IO并不在任何情况下都能提高性能。设置直接IO的开销很大,而又没有使用IO缓存的优势。比如,使用直接IO需要write系统调用同步执行;否则应用程序将会不知道什么时候能再次使用他的IO缓冲区。在每个写操作完成之前不能停止应用程序,这样会导致关闭程序缓慢,这就是使用直接IO的应用程序也使用异步IO的原因。 在字符设备中执行直接IO是不行的,也是有害的。只有确定设置缓冲IO的开销特别大,才使用直接IO。块设备和网络设备不担心实现直接IO的问题

【一篇入魂】网络编程中的五种IO模型

点点圈 提交于 2020-01-16 14:35:22
我们在进行编程开发的时候,经常会涉及到同步,异步,阻塞,非阻塞,IO多路复用等概念,这几个概念有区别,但是有时候也容易混淆,如果不总结一下的话很容易受到困扰,下面就记录一下这几个概念的理解。 Unix网络编程中的五种IO模型 Blocking IO - 阻塞IO NoneBlocking IO - 非阻塞IO IO multiplexing - IO多路复用 signal driven IO - 信号驱动IO asynchronous IO - 异步IO 由于 signal driven IO 在实际使用中并不常用,所以这里只讨论剩下的四种IO模型。 在讨论之前先说明一下IO发生时涉及到的对象和步骤,对于一个network IO,它会涉及到两个系统对象: application 调用这个IO的进程 kernel 系统内核 那他们经历的两个交互过程是: 阶段1 wait for data 等待数据准备 阶段2 copy data from kernel to user 将数据从内核拷贝到用户进程中 之所以会有同步、异步、阻塞和非阻塞这几种说法就是根据程序在这两个阶段的处理方式不同而产生的。了解了这些背景之后,我们就分别针对四种IO模型进行讲解。 Blocking IO - 阻塞IO 在linux中,默认情况下所有的socket都是blocking,一个典型的读操作流程大概如下图:

IO读写

我的未来我决定 提交于 2020-01-16 09:29:28
1、read & write read: 把数据从内核缓冲区复制到进程缓冲区。 write: 把数据从进程缓冲区复制到内核缓冲区。 上层程序的IO操作、不是物理设备级别的读写,而是缓存的复制。而内核缓冲区和物理设备之间的数据交换则是由操作系统的Kernel来完成。 2、缓冲区 缓冲区的目的:减少频繁地与设备之间的物理交换。 Linux系统中,操作系统只有一个内核缓冲区,而每个用户,有自己的独立缓冲区,叫进程缓冲区。 3、四种IO模型 同步阻塞IO(Blocking IO): 【优点】阻塞等待数据期间,用户线程挂起,不会占用CPU资源。 【缺点】为每个连接配置一个线程,在并发量大的情况下,内存、线程切换的开销会非常巨大。 【 高并发场景下不可用 】 【 Socket默认模式 】 同步非阻塞IO(Non-blocking IO) 【优点】 应用程序不断地进行IO系统调用,轮询数据是否准备好,在内核等待数据地过程中立即返回,在内核缓冲区有数据时才开始阻塞,实时性较好。 【缺点】 不断地轮询,占用大量CPU时间,效率低下。 【 高并发场景下不可用 】 IO多路复用(IO Multiplexing): 避免轮询等待问题。 【特点】 涉及两种系统调用,一种select/epoll,另一种是IO操作。select先查询注册的socket连接对应的文件描述符(轮询)

Java BIO NIO 与 AIO

二次信任 提交于 2020-01-15 22:39:14
回顾 上一章我们介绍了操作系统层面的 IO 模型。 阻塞 IO 模型。 非阻塞 IO 模型。 IO 复用模型。 信号驱动 IO 模型(用的不多,知道个概念就行)。 异步 IO 模型。 并且介绍了 IO 多路复用的底层实现中,select,poll 和 epoll 的区别。 几个概念 我们在这里在强调一下几个概念。 一个 IO 操作的具体步骤: 对于操作系统来说,进程是没有直接操作硬件的权限的,所以必须请求内核来帮忙完成。 等待数据准备好,对于一个套接字上得操作,这一步骤关系到数据从网络到达,并将其复制到内核某个缓冲区。 将数据从内核缓冲区复制到进程缓冲区。 同步和异步的区别在于第二个步骤是否阻塞,如果从内核缓冲区复制到用户缓冲区的过程阻塞,那么就是同步 IO,否则就是异步 IO。所以上面提到的前四种 IO 模型都是同步 IO,最后一种是异步 IO。 阻塞和非阻塞的区别在于第一步,发起 IO 请求是否会被阻塞,如果阻塞直到完成那么就是传统的阻塞 IO,否则就是非阻塞 IO。所以上面提到的第一种 IO 模型是阻塞 IO,其余的都是非阻塞 IO。 Java IO API 介绍完操作系统层面的 IO 模型,我们来看看,Java 提供的 IO 相关的 API。 Java 中提供三种 IO 操作的 API,阻塞 IO(BIO,同步阻塞),非阻塞 IO(NIO,同步非阻塞)和异步 IO (AIO

python之I/O操作

。_饼干妹妹 提交于 2020-01-15 18:24:27
IO在计算机中指Input/Output,也就是输入和输出。由于程序和运行时数据是在内存中驻留,由CPU这个超快的计算核心来执行,涉及到数据交换的地方,通常是磁盘、网络等,就需要IO接口。 比如你打开浏览器,访问新浪首页,浏览器这个程序就需要通过网络IO获取新浪的网页。浏览器首先会发送数据给新浪服务器,告诉它我想要首页的HTML,这个动作是往外发数据,叫Output,随后新浪服务器把网页发过来,这个动作是从外面接收数据,叫Input。所以,通常,程序完成IO操作会有Input和Output两个数据流。当然也有只用一个的情况,比如,从磁盘读取文件到内存,就只有Input操作,反过来,把数据写到磁盘文件里,就只是一个Output操作。 事件驱动模型 通常情况,有一下几种情况模型: 每收到一个请求,创建一个新的进程,来处理该请求。 每收到一个请求,创建一个新的线程,来处理该请求。 每收到一个请求,放入一个时间列表,让主进程通过非阻塞IO来处理请求。 综上普遍认为第三种方式为大多数网络服务器采用的方式。 例如在UI编程中,常常用到鼠标点击进行操作,那么如何,何时去获得鼠标的点击进行处理呢? 在前面学到的线程中,我们可以创建一个线程对鼠标进行检测。那么问题来了? CPU资源浪费,可能鼠标点击的频率非常小,但是扫描线程还是会一直循环检测,这会造成很多的CPU资源浪费

BIO、NIO、AIO入门认识

梦想与她 提交于 2020-01-14 06:57:18
同步、异步。阻塞。非阻塞概念理解 。 同步: 比如在执行某个逻辑业务,在没有得到结果之前一直处于等待阻塞状态,得到结果后才继续执行 异步: 比如在执行某个逻辑业务,在没有得到结果可以去干其他的事情,等待通知再回来执行刚才没执行完的操作。 阻塞: 比如在执行某个逻辑业务,在结果没有返回之前,当前线程会被挂起,直到有结果了才继续执行 非阻塞: 非阻塞和阻塞的概念相对应,指在不能立刻得到结果之前,该函数不会阻塞当前线程的执行,继续执行直接返回      IO、BIO、NIO、AIO Java BIO : 同步并阻塞 ,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。 Java NIO : 同步非阻塞 ,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。 Java AIO(NIO.2) : 异步非阻塞 ,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理。 IO :    IO操作分为两个部分:发起IO请求、IO数据读写,再简单一点就input和output流,作用于数据传   BIO : 同步阻塞IO   同步阻塞IO处理

java 多线程——并发编程模型 学习笔记

房东的猫 提交于 2020-01-13 03:32:53
并发编程模型 一、并行工作者模型 委派者(Delegator)将传入的作业分配给不同的worker; 每个worker完成整个任务 ; workers并行运作在不同的线程上,甚至可能在不同的 CPU 上。 缺点: a、处理共享资源复杂; b、worker无状态,需每次重读数据,某些情况下影响性能; c、任务顺序不确定。 二、事件驱动模型(流水线模型) 每个worker只负责作业中的 部分工作 ; 当完成了自己的这部分工作时工作者会将作业转发给下一个工作者; 每个工作者在自己的线程中运行,并且不会和其他工作者共享状态 ,有时也被成为无共享并行模型。 通常使用 非阻塞的 IO 来设计使用流水线并发模型的系统。 非阻塞 IO:一旦某个工作者开始一个 IO 操作的时候(比如读取文件或从网络连接中读取数据), 该工作者 不会一直等待 IO 操作的结束。IO 操作速度很慢,所以等待 IO 操作结束很浪费 CPU 时间。此时 CPU 可以做一些其他事情。当 IO 操作完成的时候,IO 操作的结果(比如读出的数据或者数据写完的状态)被传递给 下一个工作者 。 有了非阻塞 IO,就可以使用 IO 操作确定工作者之间的边界。工作者会尽可能多运行直到遇到并启动一个 IO 操作。然后交出作业的控制权。当 IO 操作完成的时候,在流水线上的下一个工作者继续进行操作,直到它也遇到并启动一个 IO 操作。 1

BIO,NIO,AIO(NIO2)的理解

杀马特。学长 韩版系。学妹 提交于 2020-01-13 02:20:02
写在前面,这里所说的IO主要是强调的网络IO 1.BIO(同步并阻塞) 客户端一个请求对应一个线程。客户端上来一个请求(最开始的连接以及后续的IO请求),服务端新建一个线程去处理这个请求,由于线程总数是有限的(操作系统对线程总数的限制或者线程池的大小),所以,当达到最大值时给客户端的反馈就是无法响应, 阻塞体现在 服务端接收客户端 连接请求 被阻塞了,还有一种阻塞是在单线程处理某一个连接时,需要一直等待IO操作完成。 同步体现在 单个线程处理请求时 调用read(write) 方法需等待读取(写)操作完成才能返回。 2.NIO(同步非阻塞) 客户端一个IO请求对应一个线程。过程是这样的,每个客户端一开始上来的连接会注册到selector中,selector会轮询注册上来的连接是否有IO请求,如果有IO请求,就创建一个线程处理该连接上的该次请求。 非阻塞体现在 服务端能够无限量(相对于BIO)的接收客户端的连接请求。 同步体现在 单个线程处理请求时 调用read(write) 方法需等待读取(写)操作完成才能返回。这种模式下,如果后端应用处理遇到资源争夺(数据库操作)而阻塞等,为提高请求的处理速度,可以在后端设立资源池或队列等,把对应的请求数据以及现场(哪个连接的哪个请求等)放入队列,前台线程立即返回处理别的IO请求。 3.AIO(NIO2)(异步阻塞)

NIO与IO的流程梳理

放肆的年华 提交于 2020-01-12 20:02:16
IO与NIO详解----面试整理 在java种我们所说的IO与NIO其实是java对操作系统的IO模型的封装而产生的接口,是我们开发人员不必关注操作系统层面的知识。 同步: 同步就是发起一个调用后,被调用者未处理完请求之前,调用不返回。 异步: 异步就是发起一个调用后,立刻得到被调用者的回应表示已接收到请求,但是被调用者并没有返回结果,此时我们可以处理其他的请求,被调用者通常依靠事件,回调等机制来通知调用者其返回结果。 传统的BIO模型 一请求一应答,客户端发起socket连接,服务端通过serversocket进行连接。但是对于多个连接请求这样的模型就没法处理了这样衍生出来的就是多线程了。 多线程处理多对多 多个连接请求发送到服务端后,服务端每收到一个请求就开一个线程去为这个请求建立连接,这样就可以完成多连接请求的需求了。 **问题一:**为什么采用多线程,而不一个一个处理连接请求呢? 答:由于socket的accept、read、write方法都是阻塞的,如果一旦一个连接需要很长时间的读写,那么后续的连接就无法及时的响应了。 **问题二:**多线程的方式有什么问题,该如何解决? 答:采用多线程去解决这种场景的问题一旦请求量过大的时候就会无休止的创建线程,但线程资源很宝贵,在linux种进程的本质就是线程,所以一旦创建一个线程调用的是系统及的函数,开销很大