linux Native AIO的使用

来源:互联网 发布:mac可以玩什么网游 编辑:程序博客网 时间:2024/05/14 20:34

linux提供了异步读写磁盘文件的接口,需要先安装libaio(centos上,yum install libaio),才能使用头文件libaio.h;异步IO可以通过eventfd与epoll结合,进而在事件驱动框架中使用。

linux native aio需要针对使用O_DIRECT标识打开的文件,造成如下限制(如果无O_DIRECT标识,在调用io_submit时,会同步完成IO操作):

  • AIO方式(O_DIRECT导致)读写文件时,无法利用操作系统对文件的缓存,只能从磁盘读写
  • 读写缓冲区的地址、读写内容的大小、读写的文件偏移必须是扇区的倍数(通常是512字节)

例子:
test_aio.c

#include<libaio.h>#include<stdlib.h>#include<errno.h>#include<stdio.h>#include<unistd.h>#define __USE_GNU 1#include<fcntl.h>#define FILEPATH "./test.txt"int main(){    io_context_t context ;    unsigned  nr_events = 10;    struct iocb io[2], *p[2]={&io[0], &io[1]};    struct io_event e[2];    struct timespec timeout;    char* wbuf = 0;    char* rbuf = 0;    int wbuflen = 512*1024*1024;    int rbuflen = wbuflen+1;    int ret = 0;    int comp_num = 0;    int i = 0;    posix_memalign((void**)&wbuf, 512, wbuflen);    posix_memalign((void**)&rbuf, 512, rbuflen);    memset(wbuf, 'a', wbuflen);    memset(rbuf, 0, rbuflen);    // memset(buf, 'a', buflen);    int fd = open(FILEPATH, O_CREAT|O_RDWR|O_DIRECT, 0644);    if(fd < 0){         printf("open file failed !\n");        return 0;    }       memset(&context, 0, sizeof(io_context_t));    if( 0 != io_setup(nr_events, &context) ){        printf("io_setup error:%d\n", errno);    }       io_prep_pwrite(&io[0], fd, wbuf, wbuflen, 0);     io_prep_pread(&io[1], fd, rbuf, rbuflen-1, 0);     if((ret = io_submit(context,2,p)) != 2){                  printf("io_submit error:%d\n", ret);                     io_destroy(context);                 return -1;        }          while(1){        timeout.tv_sec = 0;        timeout.tv_nsec = 10000000;        ret = io_getevents(context,2,2,e,&timeout);        if(ret < 0)        {               printf("io_getevents error:%d\n", ret);            break;        }           if(ret > 0)        {               comp_num += ret;            for( i = 0;i < ret; ++i){                printf("result,res2:%d, res:%d\n", e[i].res2, e[i].res);            }        }        if(comp_num >= 2){            printf("done !\n");            break;        }        printf("have not done !\n");    }    return 0;

Makefile

 all:test_aio.c     gcc -o a.out test_aio.c  -L/lib64 -laio

执行结果:

$ ./a.out result,res2:0, res:536870912have not done !have not done !have not done !have not done !result,res2:0, res:536870912done !

struct io_event中的res字段表示读到的字节数或者一个负数错误码;

除了linux nativ aio,还有Glibc AIO , 用多线程同步来模拟异步IO。
参考:
一个简单的libaio的例子
Linux异步IO编程实例分析
一个epoll/aio/eventfd结合使用的简单例子
Linux 异步IO介绍
Kernel Asynchronous I/O (AIO) Support for Linux

0 0
原创粉丝点击