Linux 异步 I/O 是 Linux 内核中提供的一个相当新的增强。它是 2.6 版本内核的一个标准特性,但是我们在 2.4 版本内核的补丁中也可以找到它。AIO 背后的基本思想是允许进程发起很多 I/O 操作,而不用阻塞或等待任何操作完成。稍后或在接收到 I/O 操作完成的通知时,进程就可以检索 I/O 操作的结果。
linux 中最常用的 IO 模型是同步 IO,在这个模型中,请求发出后应用程序会阻塞直到满足条件(阻塞 IO),或在不满足条件的情况下立即返回出错(非阻塞 IO),这样做的好处是程序在等待 IO 请求完成时不会占用 CPU。 POSIX 定义了异步 IO 应用程序接口(AIO API),linux 2.6 以上版本的内核也实现了内核级别的异步 IO 调用。 异步 IO 的基本思想是允许进程发起很多 IO 操作,而不用阻塞任何一个,也不用等待任何操作的完成,直到 IO 操作完成时,进程可以检索 IO 操作的结果。
在设备驱动中使用异步通知可以使得对设备的访问可进行时,由驱动主动通知应用程序进行访问。因此,使用无阻塞I/O的应用程序无需轮询设备是否可访问,而阻塞访问也可以被类似“中断”的异步通知所取代。异步通知类似于硬件上的“中断”概念,比较准确的称谓是“信号驱动的异步I/O”。 1、异步通知的概念和作用 影响:阻塞–应用程序无需轮询设备是否可以访问 非阻塞–中断进行通知 即:由驱动发起,主动通知应用程序 2、linux异步通知编程 2.1 linux信号 作用:linux系统中,异步通知使用信号来实现 函数原型为:
上一篇文章 主要分析了 Linux 原生 AIO 的原理和使用,而这篇要介绍的是 Linux 原生 AIO 的实现过程。
在这篇博客中,我们将探讨Linux底层的几种IO(输入/输出)方式,为鸿蒙开发者提供一个清晰的理解。本文将详细介绍阻塞IO、非阻塞IO、I/O多路复用、信号驱动IO及异步IO等概念,旨在帮助开发者优化鸿蒙应用性能。关键词:鸿蒙OS、Linux、IO模型、阻塞非阻塞、IO多路复用、性能优化。
aio_return 异步 I/O 和标准块 I/O 之间的另外一个区别是我们不能立即访问这个函数的返回状态,因为我们并没有阻塞在 read 调用上。在标准的 read 调用中,返回状态是在该函数返回时提供的。但是在异步 I/O 中,我们要使用 aio_return 函数。这个函数的原型如下: ssize_t aio_return( struct aiocb *aiocbp ); 只有在 aio_error 调用确定请求已经完成(可能成功,也可能发生了错误)之后,才会调用这个函数。aio_return 的返回值就等价于同步情况中 read 或 write 系统调用的返回值(所传输的字节数,如果发生错误,返回值就为 -1)。 aio_write aio_write 函数用来请求一个异步写操作。其函数原型如下: int aio_write( struct aiocb *aiocbp ); aio_write 函数会立即返回,说明请求已经进行排队(成功时返回值为 0,失败时返回值为 -1,并相应地设置 errno)。 这与 read 系统调用类似,但是有一点不一样的行为需要注意。回想一下对于 read 调用来说,要使用的偏移量是非常重要的。然而,对于 write 来说,这个偏移量只有在没有设置 O_APPEND 选项的文件上下文中才会非常重要。如果设置了 O_APPEND,那么这个偏移量就会被忽略,数据都会被附加到文件的末尾。否则,aio_offset 域就确定了数据在要写入的文件中的偏移量。 aio_suspend 我们可以使用 aio_suspend 函数来挂起(或阻塞)调用进程,直到异步请求完成为止,此时会产生一个信号,或者发生其他超时操作。调用者提供了一个 aiocb 引用列表,其中任何一个完成都会导致 aio_suspend 返回。 aio_suspend 的函数原型如下: int aio_suspend( const struct aiocb *const cblist[], int n, const struct timespec *timeout ); aio_suspend 的使用非常简单。我们要提供一个 aiocb 引用列表。如果任何一个完成了,这个调用就会返回 0。否则就会返回 -1,说明发生了错误。请参看清单 3。 清单 3. 使用 aio_suspend 函数阻塞异步 I/O struct aioct *cblist[MAX_LIST] /* Clear the list. */ bzero( (char *)cblist, sizeof(cblist) ); /* Load one or more references into the list */ cblist[0] = &my_aiocb; ret = aio_read( &my_aiocb ); ret = aio_suspend( cblist, MAX_LIST, NULL ); 注意,aio_suspend 的第二个参数是 cblist 中元素的个数,而不是 aiocb 引用的个数。cblist 中任何 NULL 元素都会被 aio_suspend 忽略。 如果为 aio_suspend 提供了超时,而超时情况的确发生了,那么它就会返回 -1,errno 中会包含 EAGAIN。 aio_cancel aio_cancel 函数允许我们取消对某个文件描述符执行的一个或所有 I/O 请求。其原型如下: int aio_cancel( int fd, struct aiocb *aiocbp ); 要取消一个请求,我们需要提供文件描述符和 aiocb 引用。如果这个请求被成功取消了,那么这个函数就会返回 AIO_CANCELED。如果请求完成了,这个函数就会返回 AIO_NOTCANCELED。 要取消对某个给定文件描述符的所有请求,我们需要提供这个文件的描述符,以及一个对 aiocbp 的 NULL 引用。如果所有的请求都取消了,这个函数就会返回 AIO_CANCELED;如果至少有一个请求没有被取消,那么这个函数就会返回 AIO_NOT_CANCELED;如果没有一个请求可以被取消,那么这个函数就会返回 AIO_ALLDONE。我们然后可以使用 aio_error 来验证每个 AIO 请求。如果这个请求已经被取消了,那么 aio_error 就会返回 -1,并且 errno 会被设置为 ECANCELED。 lio_listio 最后,AIO 提供了一种方法使用 lio_listio API 函数同时发起多个传输。这个函数非常重要,因为这意味着我们可以在一个系统调用(一次内核上下文切换
我们在使用 man 手册的时候,可以使用man -f [keyword]去查询keyword的在线文档, 但是这时候会报错:(图来源自网络)
如何提升存储系统的性能是一个对存储工程师们来说是永恒的大命题,解决这个问题并没有一击即中的银弹,IO性能的优化都在细节里。今天我们来讲一讲性能和IO模型之间的关系。
官网:https://oss.oracle.com/projects/libaio-oracle/,正如标题所说,非常简单了,不用多解释,请直接看头文件,其中aio_poll类似于poll,重要的结构是aiocb64,类似于epoll_event。 #ifndef _SKGAIO_H #define _SKGAIO_H #define IOCB_CMD_READ 0 #define IOCB_CMD_WRITE 1
这是05年的老文章,网上应该有人早就翻译过了,我翻译它仅仅为了学习Reactor/Proactor两种TCP服务器设计模式,顺便作翻译练习。
本文主要分析了虚拟机在IO方面的性能,并对不同类型的虚拟机的IO进行了对比。通过在Ceph集群上对虚拟机进行IO测试,得出了不同虚拟机类型在IO方面的性能差异。同时,根据测试结果,提出了优化方案,以降低虚拟机IO对存储集群的影响。
epoll 是 Linux 系统中常用的多路复用 I/O 组件,一般用于监听 socket 是否能够进行 I/O 操作。那么,epoll 能监听普通文件吗?
iOS 12在几周前发布了,并带来了许多安全方面的修复和改进。特别是,这个新版本碰巧修补了我们在Synacktiv发现的一个很厉害的内核漏洞。
接触网络编程,我们时常会与各种与IO相关的概念打交道:同步(Synchronous)、异步(ASynchronous)、阻塞(blocking)和非阻塞(non-blocking)。关于概念的区别在知乎上看到一位朋友(链接)打了一个比较形象的比喻:
接着上篇文章VFS- 内核是如何抽象文件系统的阐述了VFS以后,这篇文章主要想讲述一下在内核当中如何创建一个文件系统.其实根据上一篇博客来说,我们的文件系统主要能够满足VFS的抽象,就可以在内核中构建一个自己的文件系统.一个文件系统满足的功能其实就是针对文件的增删改查,目录的管理,还有链接等等,这是从用户的角度来看,而文件系统本身也要有自己的状态信息,维护在超级块里,可以被挂载,然后向下要提交IO请求(一般是磁盘也可以是网络,甚至是内存).这里的实现我们选择在内存当中实现一个文件系统.
标题有点简单粗暴,直接用了本文要介绍的几个概念。本来想取个高大上一点的标题,但是感觉主题不那么明了。
周日午后,刚刚放下手里的电话,正在给刚刚的面试者写评价。刚刚写到『对Linux的基本IO模型理解不深』这句的时候,女朋友突然出现。
单机存储引擎负责高效的组织数据、索引数据、保存数据,为上层应用提供易用的接口。有一类存储引擎为了得到更高的性能,会跨过文件系统这一层调用,直接操作裸盘。那么如何实现这类存储引擎呢?本文希望以 Ceph BlueStore 为例子,介绍一下其中的实现方法。
recvfrom -> [syscall -> wait -> copy ->] return OK!
在RTOS中,本质也是去读写寄存器,但是需要有统一的驱动程序框架。 所以:RTOS驱动 = 驱动框架 + 硬件操作
User space(用户空间)和 Kernel space(内核空间)。Linux里面这么设计的目的主要是为了安全,即使用户空间崩溃了,内核也不受影响。所以在Linux世界,进程不能直接访问硬件设备,当进程需要访问硬件设备(比如读取磁盘文件,接收网络数据等等)时,必须由用户态模式切换至内核态模式,通过系统调用访问硬件设备。
然后通过系统调用去read一个文件,为什么man 2 read的时候或者man 2 write的时候的参数与写的驱动的read和write里面定义的函数看上去不同呢?
一个典型的IO操作包括了两个阶段,数据准备和数据读写。比如说现在要使用 recv 执行一个读操作,数据就绪就是远端是否有数据可读。
文件的写入是否是原子的?多个线程写入同一个文件是否会写错乱?多个进程写入同一个文件是否会写错乱?想必这些问题多多少少会对我们产生一定的困扰,即使知道结果,很多时候也很难将这其中的原理清晰的表达给提问者
作为程序员,在日常工作中,都或多或少的接触过网络I/O这个概念,接触过网络编程,听说过socket等等,但是对于更深层次的理解,多少还是有点欠缺,通过本文,可以了解网络中最重要的模块I/O,以及对几种网络模型的介绍,在我们日常工作开发过程中,可以针对特定需求,选择特定的网络模型,达到事半功倍的效果。
同步阻塞模式。在JDK1.4以前,使用Java建立网络连接时,只能采用BIO方式,在服务器端启动一个ServerSocket,然后使用accept等待客户端请求,对于每一个请求,使用一个线程来进行处理用户请求。线程的大部分时间都在等待请求的到来和IO操作,利用率很低。而且线程的开销比较大,数量有限,因此服务器同时能处理的连接数也很低。
下图是根据同步、异步、阻塞、非阻塞四个指标总结的Linux下四个象限的I/O通信模式。
关注:被调用者 B 是否有消息通知(回调函数)机制 把 最终结果 返回给 A。
在 Unix 的世界里,有句很经典的话:一切对象皆是文件。这句话的意思是说,可以将 Unix 操作系统中所有的对象都当成文件,然后使用操作文件的接口来操作它们。Linux 作为一个类 Unix 操作系统,也努力实现这个目标。
POSIX AIO 是在用户控件模拟异步 IO 的功能,不需要内核支持,而 linux AIO 则是 linux 内核原声支持的异步 IO 调用,行为更加低级。
磁盘IO是非常缓慢的,Linux内核为了减少磁盘的IO次数,在系统调用后,会把用户数据拷贝到内核缓存起来,这个内核缓存空间称之为页缓存。
作为程序员,在日常工作中,都或多或少的接触过网络I/O这个概念,接触过网络编程,听说过socket等等,但是对于更深层次的理解,多少还是有点欠缺,通过本文,可以了解网络中最重要的模块I/O,以及对几种网络模型的介绍,在我们日常工作开发过程中,可以针对特定需求,选择特定的网络模型,达到事半功倍的效果。
本文会涉及到阻塞、非阻塞、多路复用、同步、异步、BIO、NIO、AIO等几个知识点,知识点虽然不难但经常容易搞混,这次带领大家再回顾一遍。
本文从操作系统的角度来解释BIO,NIO,AIO的概念,含义和背后的那些事。本文主要分为3篇。 第一篇 讲解BIO和NIO以及IO多路复用 第二篇 讲解磁盘IO和AIO 第三篇 讲解在这些机制上的一些应用的实现方式,比如nginx,nodejs,Java NIO等 磁盘IO 磁盘IO,简单来说就是读取硬盘一类设备的IO。这类设备包括传统的磁盘、SSD、闪存、CD等。操作系统将其统一抽象为”块设备“。所以磁盘IO又可以叫做”块IO“。这些设备上的数据一般用文件系统来组织,所以又可以成为”文件IO“。本文统
磁盘IO,简单来说就是读取硬盘一类设备的IO。这类设备包括传统的磁盘、SSD、闪存、CD等。操作系统将其统一抽象为”块设备“。所以磁盘IO又可以叫做”块IO“。这些设备上的数据一般用文件系统来组织,所以又可以成为”文件IO“。本文统一用”磁盘IO“这个术语。
承接上文的操作系统,关于IO会涉及到阻塞、非阻塞、多路复用、同步、异步、BIO、NIO、AIO等几个知识点。知识点虽然不难但平常经常容易搞混,特此Mark下,与君共勉。
在Linux系统编程中,IO流(Input/Output Streams)是一个非常重要的概念。高级IO流是基于基本IO操作(如read、write等)之上的扩展,提供了更强大的功能和更高效的操作方式。本文将深入探讨Linux中的高级IO流,重点介绍其原理和使用方法,并提供相应的C++代码示例。
Linux Asynchronous I/O Explained (Last updated: 13 Apr 2012) ******************************************************************************* by Vasily Tarasov <tarasov AT vasily dot name> Asynchronoes I/O (AIO) is a method for performing I/O oper
Reactor是基于同步I/O的, 他要求主线程(I/O处理单元)只负责监听文件描述符上是否有事件发生, 有的话就立刻将该事件通知给工作线程(逻辑单元). 初次之外, 主线程不做任何其他实质性的工作. 读写数据, 接受新的连接, 以及处理客户请求均在工作线程中完成.
http://blog.csdn.net/zs634134578/article/details/19806429
在日常开发中一些看似司空见惯的问题上,我觉得可能大多数人其实并没有真正理解,或者理解的不够透彻。不信我们来看以下一段简单的读取文件的代码:
Linux 上可用的 C 编译器是 GNU C 编译器,它建立在自由软件基金会的编程许可证的基础上,因此可以自由发布。GNU C对标准C进行一系列扩展,以增强标准C的功能。
Linux/Unix五种I/O模型 内容来源,侵删。 游双-《Linux高性能服务器编程》 牛客网-Linux高并发服务器开发 ---- 阻塞-blocking 调用者调用了某个函数,然后等待这个函数返回,在这期间什么都不做,不停的去检查这个函数有没有返回,应用程序必须等这个函数返回才能进行下一步的动作。 即,针对阻塞I/O执行的系统调用可能因为无法立即完成而被操作系统挂起,直到等待的时间发生为止,才可以继续执行下一步的操作。 可能被阻塞的系统调用包括accept、send、rec
这一期我们来看一下有哪些办法可以减少linux下的文件碎片。主要是针对磁盘长期满负荷运转的使用场景(例如http代理服务器);另外有一个小技巧,针对互联网图片服务器,可以将io性能提升数倍。如果为服务器订制一个专用文件系统,可以完全解决文件碎片的问题,将磁盘io的性能发挥至极限。对于我们的代理服务器,相当于把io性能提升到3-5倍。 在现有文件系统下进行优化linux内核和各个文件系统采用了几个优化方案来提升磁盘访问速度。但这些优化方案需要在我们的服务器设计中进行配合才能得到充分发挥。 文件系统缓存lin
说到IO模型,都会牵扯到同步、异步、阻塞、非阻塞这几个词。从词的表面上看,很多人都觉得很容易理解。但是细细一想,却总会发现有点摸不着头脑。自己也曾被这几个词弄的迷迷糊糊的,每次看相关资料弄明白了,然后很快又给搞混了。
我们都知道unix世界里、一切皆文件、而文件是什么呢?文件就是一串二进制流而已、不管socket、还是FIFO、管道、终端、对我们来说、一切都是文件、一切都是流、在信息交换的过程中、我们都是对这些流进行数据的收发操作、简称为I/O操作(input and output)、往流中读出数据、系统调用read、写入数据、系统调用write、不过话说回来了、计算机里有这么多的流、我怎么知道要操作哪个流呢?做到这个的就是文件描述符、即通常所说的fd(file descriptor)、一个fd就是一个整数、所以对这个整数的操作、就是对这个文件(流)的操作、我们创建一个socket、通过系统调用会返回一个文件描述符、那么剩下对socket的操作就会转化为对这个描述符的操作、不能不说这又是一种分层和抽象的思想、
领取专属 10元无门槛券
手把手带您无忧上云