您的位置:首页 > 运维架构 > Linux

linux Native AIO的使用

2016-02-22 20:45 369 查看
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:536870912
have not done !
have not done !
have not done !
have not done !
result,res2:0, res:536870912
done !


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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: