爱编码的Farmer

  • 主页
  • 编程开发
  • 运营维护
  • 随心笔记
  • 留言页面
  • 打赏
爱编码的Farmer
我是Farmer,我为自己代言
  1. 首页
  2. 编程开发
  3. 教程笔记
  4. 正文

linux aio 异步io

2018年10月5日 8705点热度 1人点赞 3条评论

linux下的aio有glibc的和内核所提供的,glibc是使用的多线程的模式模拟的,另外一种是真正的内核异步通知了,已经使用在了nginx上,前面看了一下swoole的实现,是类似与glibc那种多线程的模式。不过两种方法都有一定的毛病,多线程模拟自然是有所效率损失,然而内核不能利用系统的缓存,只能以 O_DIRECT 方式做直接 IO,所以看知乎上有一个linux下的异步IO(AIO)是否已成熟?的问题,不过那是2014年的事情了,不知道现在怎么样。

在此之前需要安装好 libaio

sudo apt install libaio-dev

函数

头文件:#include <libaio.h>

例子

一个一步读取文件内容的例子

#include <stdio.h>
#include <fcntl.h>
#include <libaio.h>
#include <malloc.h>
#include <mhash.h>

#define MAX_EVENT 10
#define BUF_LEN 1024

void callback(io_context_t ctx, struct iocb *iocb, long res, long res2) {
    printf("test call\n");
    printf("%s\n", iocb->u.c.buf);
}

int main() {
    int fd = open("/home/huanl/client.ovpn", O_RDONLY, 0);
    io_context_t io_context;
    struct iocb io, *p = &io;
    struct io_event event[MAX_EVENT];
    char *buf = malloc(BUF_LEN);
    memset(buf, 0, BUF_LEN);
    memset(&io_context, 0, sizeof(io_context));

    if (io_setup(10, &io_context)) {
        printf("io_setup error");
        return 0;
    }
    if (fd < 0) {
        printf("open file error");
        return 0;
    }
    io_prep_pread(&io, fd, buf, BUF_LEN, 0);
    io_set_callback(&io, callback);
    if (io_submit(io_context, 1, &p) < 0) {
        printf("io_submit error");
        return 0;
    }

    int num = io_getevents(io_context, 1, MAX_EVENT, event, NULL);
    for (int i = 0; i < num; i++) {
        io_callback_t io_callback = event[i].data;
        io_callback(io_context, event[i].obj, event[i].res, event[i].res2);
    }

    return 0;
}

参考

https://jin-yang.github.io/post/linux-program-aio.html

标签: 暂无
最后更新:2018年10月7日

Farmer

不敢说什么

点赞
< 上一篇
下一篇 >

文章评论

  • xi2008wang

    open时加上O_DIRECT标志,程序执行出错了,返回值-22,不知道为什么。。。
    另外libaio库官方文档不知道在哪,google找不到。。。。

    2019年1月14日
    回复
    • Farmer

      @xi2008wang http://www.fsl.cs.sunysb.edu/~vass/linux-aio.txt 感觉是这个,英文的我看起来也有点头疼

      2019年1月14日
      回复
      • xi2008wang

        @Farmer 经过大量搜索,差不多明白了:
        Linux aio:linux可扩展性项目的子项目:官网http://lse.sourceforge.net/io/aio.html
        libaio:是aio 系统调用的封装:官网https://pagure.io/libaio/tree/master

        根据官网:these do not return an explicit error, but quietly default to synchronous or rather non-AIO behaviour
        及最新文章https://blog.cloudflare.com/io_submit-the-epoll-alternative-youve-never-heard-about/
        目前的aio还是不支持buffer io,你的程序正常是变成同步了,其实还是阻塞在了io_submit。

        我加入了标志O_DIRECT,程序异常返回-22,其标号是EINVAL。
        异常原因是没有对齐块,我将内存分配由malloc改成posix_memalign,程序就正常了。

        2019年1月16日
        回复
  • 取消回复

    此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据。

    COPYRIGHT © 2021 icodef.com. ALL RIGHTS RESERVED.

    Theme Kratos Made By Seaton Jiang

    湘ICP备19008073号