Linux Native Aio 异步AIO的研究

Linux Native Aio 异步AIO的研究

http://rango.swoole.com/archives/282

首先声明一下epoll+nonblock从宏观角度可以叫做全异步,但从微观的角度来看还是同步的IO。只是在数据到达后得到系统通知,然后同步执行recv取回数据,没有iowait。

真正的异步IO(下面会统一叫做AIO)应该像Windows IOCP一样,传入文件句柄,缓存区,尺寸等参数和一个函数指针,当操作系统真正完成了IO操作,再执行对应的函数。

实际上对于socket来说,epoll已经是最高效的模型了,虽然比AIO多一次recv系统调用,但总体来看没有任何IO等待,效率很高。而且epoll是天然的reactor模型,程序实现更容易。AIO如windows的IOCP,是异步回调的方式,开发难度很高。

为什么还是需要AIO呢,原因是文件句柄跟socket完全不同,它总是处于可读状态。不能使用epoll+nonblock来实现异步化。如果在一个epoll的全异步Server中,要读写文件那必须得使用AIO。下面说下AIO的几种实现方案。

gcc AIO
gcc遵循posix标准实现了AIO。头文件为 <aio.h>,支持FreeBSD/Linux。是通过阻塞IO+线程池来实现的。主要的几个函数是aio_read/aio_write/aio_return。

优点:支持平台多,兼容性好,无需依赖第三方库,阻塞IO可以利用到操作系统的PageCache。

缺点:据说有一些bug和陷阱,一直未解决。不过这个都是网上文章中讲的,gcc发展这么多年,不至于还有遗留bug吧。这里有待测试。

Linux Native Aio
由操作系统内核提供的AIO,头文件为<linux/aio_abi.h>。Native Aio是真正的AIO,完全非阻塞异步的,而不是用阻塞IO和线程池模拟。主要的几个系统调用为io_submit/io_setup/io_getevents。

优点:由操作系统提供,读写操作可以直接投递到硬件,不会浪费CPU。

缺点:仅支持Linux,必须使用DirectIO,所以无法利用到操作系统的PageCache。对于写文件来说native aio的作用不大,应为本身写文件就是先写到PageCache上,直接返回,没有IO等待。

Libeio
libev的作者开发的AIO实现,与gcc aio类似也是使用阻塞IO+线程池实现的。优点与缺点参见上面。它与gcc aio的不同之处,代码更简洁,所以bug少更安全稳定。但这是一个第三方库,你的代码需要依赖libeio。

总结
如果你的程序读写的文件很大,随即性强,这样PageCache的命中率低,那可以选择Native AIO,降低CPU使用率。

如果读写的文件很小,而且是固定的一些文件,这样PageCache的命中率高,可以选择gcc aio或者libeio。

时间: 2025-01-12 14:16:58

Linux Native Aio 异步AIO的研究的相关文章

linux系统中各个路由表的研究

linux中有0~255共256张路由表.其中0号表示unspec(未指定),253,254,255分别表示default.main.local表.除了以上4张表外的其他表都是留给用户指定的表.现在就说下以上5张系统表的作用. 首先是0号表unspec.这张表可以理解成所有路由表的总和,也就是说所有路由表中的路由条目在这个表中都会有一条相对应.这样如果想看看系统中所有路由表的路由条目就可以看这张表.当然对这张表中的路由条目操作也等同于对其他表中对应的路由条目操作,因此可要小心千万别清空这个路由表

关于linux系统如何实现fork的研究(二)

本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ 引言 前一篇关于linux系统如何实现fork的研究(一)通过代码已经说明了从用户态怎么通过软中断实现调用系统调用clone函数,而clone函数的精华copy_process函数就在此篇文章中进行分析.我们知道,在linux系统中,应用层可以创建子进程和子线程(轻量级进程)两种程序分支结构.而对于linux内核而且,并不详细区分子进程和子线程(轻量级进程)的区别,他们都使用的是task_struct结构(此

拿搬东西来解释udp tcpip bio nio aio aio异步

[群主]雷欧纳德简单理解 tcpip是有通信确认的面对面通信   有打招呼的过程  有建立通道的过程 有保持通道的确认    有具体传输 udp是看到对面的人好像在对面等你 就往对面扔东西[群主]雷欧纳德基本上 好比从货车a  运东西到货车b   tcpip是建立人手互传的方式   udp是 a货车里搬出的东西直接往b货车的人方向扔  你接成功没有  散架没 我扔的一方不管的 tcp管这个 ip是通道[群主]雷欧纳德ip是手语  高速对面 我在等你  或者我要发过来了 这一类的 [群主]雷欧纳德

Java aio(异步网络IO)初探

按照<Unix网络编程>的划分,IO模型可以分为:阻塞IO.非阻塞IO.IO复用.信号驱动IO和异步IO,按照POSIX标准来划分只分为两类:同步IO和异步IO.如何区分呢?首先一个IO操作其实分成了两个步骤:发起IO请求和实际的IO操作,同步IO和异步IO的区别就在于第二个步骤是否阻塞,如果实际的IO读写阻塞请求进程,那么就是同步IO,因此阻塞IO.非阻塞IO.IO服用.信号驱动IO都是同步IO,如果不阻塞,而是操作系统帮你做完IO操作再将结果返回给你,那么就是异步IO.阻塞IO和非阻塞IO

再谈一次关于Java中的 AIO(异步IO) 与 NIO(非阻塞IO)

今天用ab进行压力测试时,无意发现的: Requests per second:    xxx [#/sec] (mean) ab -n 5000 -c 1000 http://www:8080/upload/5kb.jpg    (NIOServer: 700     AIO: 400) ab -n 5000 -c 1000 http://www:8080/upload/18kb.jpg  (NIOServer: 560     AIO: 360) ab -n 2000 -c 100  htt

linux 下同步异步,阻塞非阻塞的一些想法

同步异步 阻塞非阻塞 今天和小伙伴讨论了这个问题,网上的说法有很多种,我按照自己的思路总结一边. 一句话总结区别: 同步异步关注的是事件发生时你的行为. 阻塞非阻塞关注的是的等待事件的状态. 下面看具体的分析 同步异步 同步: 在事件发生前,你的状态是时刻关注此事件,等待此事件给你返回结果. 例子: 烧水,同步就是你时刻关注着它,一段时间后,烧水壶冒烟了,你看见了,你知道水已经烧好. 那么在这段时间内你需要一直看着它是否冒烟. 异步: 在事件发生前,你并不关心此事件,而是自己去忙自己的,事件完成

Linux下启用异步IO

#是否已经安装了AIO包#rpm -qa|grep aiolibaio-0.3.107-10.el6.x86_64libaio-devel-0.3.107-10.el6.x86_64libsane-hpaio-3.12.4-4.el6_4.1.x86_64 #数据库在链接时是否已经加载了aio的包$/usr/bin/ldd $ORACLE_HOME/bin/oracle | grep libaio        libaio.so.1 => /lib64/libaio.so.1 (0x00000

linux驱动的异步通知(kill_fasync,fasync)---- 驱动程序向应用程序发送信号

应用程序 [cpp] view plain copy #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> #include <poll.h> #include <signal.h> #include <sys/types.h> #include <unistd.h> #include <fcn

简述linux同步与异步、阻塞与非阻塞概念以及五种IO模型

1.概念剖析 相信很多从事linux后台开发工作的都接触过同步&异步.阻塞&非阻塞这样的概念,也相信都曾经产生过误解,比如认为同步就是阻塞.异步就是非阻塞,下面我们先剖析下这几个概念分别是什么含义. 同步:所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回.也就是必须一件一件事做,等前一件做完了才能做下一件事. 例如普通B/S模式(同步):提交请求->等待服务器处理->处理完毕返回 这个期间客户端浏览器不能干任何事 异步:异步的概念和同步相对.当一个异步过程