如下:
extern int io_setup(int maxevents, io_context_t *ctxp);
extern int io_destroy(io_context_t ctx);
extern int io_submit(io_context_t ctx, long nr, struct iocb *ios[]);
extern int io_cancel(io_context_t ctx, struct iocb *iocb, struct io_event *evt);
extern int io_getevents(io_context_t ctx_id, long min_nr, long nr, struct io_event *events, struct timespec *timeout);
io_setup函数:
此系统调用用于创建一个同步io环境,可以同时处理maxevents个操作,ctxp必须初始化为0,io_setup会自动分配填充空间,所以,调用后一定要掉用io_destroy进行释放掉。
返回值:
成功为0,失败为以下值
EAGAIN:maxevents已经超过个系统用户的限制,即文件/proc/sys/fs/aio-max-nr中的数字
EFAULT:分配给ctxp的指针无效
EINVAL:ctxp未初始化为0或者maxevents超限。
ENOMEM:内核资源不足。(说明系统压力大)
ENOSYS:未实现此系统调用
io_destroy函数:
释放io_setup创建的异步io环境,系统调用将尝试取消针对ctx_id的所有未完成的异步I/O操作,阻塞在不能不取消的操作上直到操作完成。
返回值:
成功为0,失败为以下值
EFAULT:分配给ctxp的指针无效
EINVAL:分配给ctxp的指针无效
ENOSYS:未实现此系统调用
io_submit函数:提交事件
将ios设置的事件,提交到ctx队列中,等待事件排队处理。
返回值:
成功:0~nr
EAGAIN:系统内资源不够用。
EBADF:提交的文件描述符不对,可能是不支持异步操作的文件描述符或者无用已关闭的文件描述符。
EFAULT:某一部分指针无效
EINVAL:参数有问题,检查参数设置。
io_cancel函数:
io_cancel()系统调用试图取消以前用io_submit(2)提交的异步I/O操作。iocb参数描述要取消的操作,ctx参数是提交操作的异步环境上下文。如果操作被成功取消,则事件将被复制到由结果指向的内存中,而不会被放到完成队列中。
返回值:
成功0,失败如上
io_getevents函数:
io_getevents系统调用读取ctx异步环境中至少min_nr至多nr个事件,(前提是timeout为NULL阻塞到至少符合条件数目的事件,如果设置超时,则在一定的时间后返回)
返回值:成功则为完成的事件,0则表示没有完成的事件。失败如上。
完整示例如下:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <libaio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#define MYLOG(iRet) fprintf(stderr,"%s %d %s \n",__FILE__,__LINE__,strerror(iRet))
#define AIO_MAX 64
int filefd1;
int filefd2;
int globle=0;
void wt_func(io_context_t ctx, struct iocb *iocb, long res, long res2 )
{
}
void rd_func( io_context_t ctx, struct iocb *iocb, long res, long res2 )
{
globle++;
if ( ((char *)(iocb->u.c.buf))[0] != '\0' )
printf("读取:[%s][%d] %s\n",(char *)iocb->u.c.buf,globle,__func__);
}
int main(){
int iRet=0;
unsigned nr_events;
unsigned aiobufsize;
long long offset;
char * aiobuf;
int eventnum;
int ievent;
int isubmit=0;
int filesize =0 ;
struct stat file1stat;
struct iocb * iocpp[AIO_MAX];
io_context_t ctx_idp;
struct io_event events[AIO_MAX];
io_callback_t cb;
struct iocb * aio;
nr_events = AIO_MAX;
filefd1 = open("./aio.txt",O_RDWR,0666);
if ( filefd1 == -1 )
{
MYLOG(errno);
exit(errno);
}
filefd2 = open("./aio2.txt",O_RDWR,0666);
if ( filefd2 == -1 )
{
MYLOG(errno);
exit(errno);
}
iRet = fstat(filefd1,&file1stat);
if ( iRet )
{
MYLOG(iRet);
exit(iRet);
}
aiobufsize = (file1stat.st_size-(file1stat.st_size%4))/4 ;
filesize = file1stat.st_size;
isubmit = 4+1;
int memnum = 0;
for (memnum =0 ;memnum<AIO_MAX; memnum++ )
{
iocpp[memnum] = ( struct iocb *)malloc(sizeof(struct iocb ) );
}
offset = 0;
iRet=io_queue_init(nr_events,&ctx_idp);
//iRet=io_setup(nr_events,&ctx_idp);
if ( iRet )
{
MYLOG(iRet);
exit(iRet);
}
int submittemp;
for ( submittemp=0;submittemp < isubmit;submittemp++)
{
if ( filesize <= aiobufsize )
{
aiobufsize = filesize;
}
else
{
filesize = filesize - aiobufsize;
}
iRet = posix_memalign((void **)&aiobuf,getpagesize(), aiobufsize);
if ( iRet )
{
MYLOG(iRet);
exit(iRet);
}
memset(aiobuf,0x00,(size_t)sizeof(aiobuf));
printf("提交:[%d][%p]\n",submittemp,iocpp[submittemp]);
io_prep_pread( iocpp[submittemp],filefd1,aiobuf,aiobufsize,offset );
io_set_callback(iocpp[submittemp],rd_func);
iRet = io_submit(ctx_idp, 1, &iocpp[submittemp]);
if ( iRet < 0 )
{
MYLOG(iRet);
exit(iRet);
}
printf("读取:[%s][%d][%lld][%p][%p]\n",(char *)iocpp[submittemp]->u.c.buf,globle,offset,iocpp[submittemp]->u.c.buf,aiobuf);
offset = offset + aiobufsize;
}
eventnum = io_getevents(ctx_idp,1,AIO_MAX,events,NULL);
if ( eventnum < 0 )
{
MYLOG(iRet);
exit(iRet);
}
printf("\n得到事件:[%d]\n",eventnum);
for ( ievent=0 ;ievent<eventnum;ievent++ )
{
aio = NULL;
cb = (io_callback_t) events[ievent].data;
aio = events[ievent].obj;
printf("事件:[%d][%p] [%p]\n",ievent,aio,&events[ievent]);
cb(ctx_idp, aio, events[ievent].res, events[ievent].res2);/*调用设置的rd_func函数*/
}
for (memnum =0 ;memnum<AIO_MAX; memnum++ )
{
free(iocpp[memnum]);
}
free(aiobuf);
io_destroy(ctx_idp);
printf("总共调用:%d \n",globle);
return 0;
}