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。

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

  1. 浅析Linux Native AIO的实现

    前段时间在自研的基于iSCSI的SAN 上跑mysql,CPU的iowait很大,后面改用Native AIO,有了非常大的改观.这里简单总结一下Native AIO的实现.对于以IO为最大瓶颈的数据 ...

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

    本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ 引言 前一篇关于linux系统如何实现fork的研究(一)通过代码已经说明了从用户态怎么通过软中断实现调用系统调 ...

  3. Linux 多线程 - 线程异步与同步机制

    Linux 多线程 - 线程异步与同步机制 I. 同步机制 线程间的同步机制主要包括三个: 互斥锁:以排他的方式,防止共享资源被并发访问:互斥锁为二元变量, 状态为0-开锁.1-上锁;开锁必须由上锁的 ...

  4. 关于linux系统如何实现fork的研究(二)【转】

    转自:http://www.aichengxu.com/linux/7166015.htm 本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ 引言 前一篇关于li ...

  5. react native 之异步请求

    第一章 异步请求  fetch的运用 在react native  中异步请求一般用fetch这个方法, fetch的格式如下: const params ={ "charset" ...

  6. Oracle在Linux下使用异步IO(aio)配置

    1.首先用root用户安装以下必要的rpm包 # rpm -Uvh libaio-0.3.106-3.2.x86_64.rpm# rpm -Uvh libaio-devel-0.3.106-3.2.x ...

  7. Oracle 之 AIO (异步io)

    Linux 异步 I/O (AIO)是 Linux 内核中提供的一个增强的功能.它是Linux 2.6 版本内核的一个标准特性,AIO 背后的基本思想是允许进程发起很多 I/O 操作,而不用阻塞或等 ...

  8. Java网络编程 -- AIO异步网络编程

    AIO中的A即Asynchronous,AIO即异步IO.它是异步非阻塞的,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理,一般我们的业务处理逻辑会变成一个回调函数,等待IO操 ...

  9. Java AIO 异步IO应用实例

    项目地址:https://github.com/windwant/aio-test Server: package org.windwant.aio; import java.io.IOExcepti ...

随机推荐

  1. Stack and Heap 堆和栈的区别

    在和计算机内存打交道时,我们一定会碰到堆和栈,这两个东西很容易搞混,那么现在就来梳理一下二者的关系. 栈是用来静态分配内存的而堆是动态分配内存的,它们都是存在于计算机内存之中. 栈的分配是在程序编译的 ...

  2. Qt 程序和窗口添加图标

    Qt项目在打包发布之后都需要有个个性的程序图标和窗口图标,这样会使程序更加美观大方,下面我们分别来看如何给程序和窗口分别添加图标.我们需要两种格式的图片,一种是.ico的,用来给程序添加图标,一种是. ...

  3. [APAC]自动发送邮件

    $lastMon = ((get-date).AddDays(-7) -split(" "))[0] $lastFri = ((get-date).AddDays(-3) -spl ...

  4. MySql之触发器【过度变量 new old】

    trigger是由事件触发某个操作.这些事件包括insert语句.update语句和delete语句.当数据库执行这些事件时,就会激活触发器执行相应的操作. [1]只有一个执行语句 create tr ...

  5. Asp.Net:Repeater 详情 备用

    页面 repeator就想for循环一样,没有编辑模板,有删除delete和详情detail模板 <%@ Page Language="C#" AutoEventWireup ...

  6. Jenkins学习记录

    参考资料 官方文档 用MSBuild和Jenkins搭建持续集成环境(1) 用MSBuild和Jenkins搭建持续集成环境(2) 构建基于Jenkins + Github的持续集成环境 Jenkin ...

  7. JavaScript数据类型(转)

    JavaScript中有5种简单数据类型(也称为基本数据类型):Undefined.Null.Boolean.Number和String.还有1种复杂数据类型——Object,Object本质上是由一 ...

  8. mysql 密码篇

    通过MySQL命令行,可以修改MySQL数据库的密码,下面就为您详细介绍该MySQL命令行,如果您感兴趣的话,不妨一看. 格式:mysqladmin -u用户名 -p旧密码 password 新密码 ...

  9. 【转】Java 5种字符串拼接方式性能比较。

    最近写一个东东,可能会考虑到字符串拼接,想了几种方法,但对性能未知,于是用Junit写了个单元测试. 代码如下: import java.util.ArrayList; import java.uti ...

  10. 蓝牙的AVDTP协议笔记

    1.概述    AVDTP(AUDIO/VIDEO DISTRIBUTION TRANSPORT PROTOCOL)是用来描述音频/视频在蓝牙设备间的传输的协议,是A2DP协议的基础协议,其在协议栈中 ...