先查看下/usr/include/aio.h中aiocb的定义
| /* Asynchronous I/O control block. */ struct aiocb { int aio_fildes; /* File desriptor. */ 涉及到的文件句柄,用户填写 int aio_lio_opcode; /* Operation to be performed. */ 执行操作,此位aio_read()会填写 int aio_reqprio; /* Request priority offset. */ 优先权等级 volatile void *aio_buf; /* Location of buffer. */ buffer位置,用户填写 size_t aio_nbytes; /* Length of transfer. */ buffer长度,用户填写 struct sigevent aio_sigevent; /* Signal number and value. */ 可以定义信号和call back的过程 /* Internal members. */ struct aiocb *__next_prio; int __abs_prio; int __policy; int __error_code; __ssize_t __return_value; #ifndef __USE_FILE_OFFSET64 __off_t aio_offset; /* File offset. */ 操作的文件偏移 char __pad[sizeof (__off64_t) - sizeof (__off_t)]; #else __off64_t aio_offset; /* File offset. */ #endif char __unused[32]; }; |
直接上了一个例子,学习下aio接口.
在必须验证每次读操作的结果的要求下,这个例子给出了两种方案。
第一种方案是:wait_aio,即执行了aio_read()后,循环检查aio_return返回,这样的方式相比阻塞型的read()没有多少优势
第二种方案是:call_back,即执行aio_read()的同时,定义该操作响应信号和回调函数。而程序可以继续执行下去。当本次read()操作有结果时,自动执行call_back_handler函数。 (推荐)
| #include <stdio.h> #include <unistd.h> #include <aio.h> #include <string.h> #include <errno.h> #include <stdlib.h> #define MAXBUF 256 #define BUFSIZE 20 struct aiocb my_aiocb; int wait_aio(int fd) { int ret; bzero((char *) &my_aiocb,sizeof(struct aiocb)); my_aiocb.aio_buf = malloc(BUFSIZE+1); if (!my_aiocb.aio_buf) { perror("malloc"); } my_aiocb.aio_fildes = fd; my_aiocb.aio_nbytes = BUFSIZE; my_aiocb.aio_offset = 0; 异步读文件 ret = aio_read(&my_aiocb); if ( ret < 0 ) { perror("aio read"); } 如果正在读文件,一直循环等待,和同步io的效果差不多
while (aio_return(&my_aiocb) == EINPROGRESS); if ( (ret=aio_return(&my_aiocb)) > 0 ) { printf("%s",my_aiocb.aio_buf); } else { perror("aio read"); } } 回调函数,把buffer的内容打印出来
int call_back_handler(sigval_t sigval) { struct aiocb *req; req = (struct aiocb*)sigval.sival_ptr; printf("call back handler/n"); printf("%s",req->aio_buf); } int call_back(int fd) { int ret; bzero((char *) &my_aiocb,sizeof(struct aiocb)); my_aiocb.aio_buf = malloc(BUFSIZE+1); my_aiocb.aio_fildes = fd; my_aiocb.aio_nbytes = BUFSIZE; my_aiocb.aio_offset = 0; 设置读写完成后事件的通知方式 可以使用回调函数,和信号,这里使用回调函数方式
my_aiocb.aio_sigevent.sigev_notify = SIGEV_THREAD; my_aiocb.aio_sigevent.sigev_notify_function = call_back_handler; my_aiocb.aio_sigevent.sigev_notify_attributes = NULL; my_aiocb.aio_sigevent.sigev_value.sival_ptr = &my_aiocb; printf("aio_read/n"); ret = aio_read(&my_aiocb); if ( ret < 0 ) { perror("aio read"); } } int main(int argc,char** argv) { char filename[MAXBUF]; int fd; // strcpy(argv[1],filename); fd=open("test.txt",O_RDONLY); if ( fd < 0 ) { return -1; } 调用等待方式
wait_aio(fd); 调用回调函数方式 call_back(fd); } 程序在编译时需要runtime库支持,不知道这个库是否支持嵌入式平台, gcc -o test_aio test_aio.o -lrt
|
| |
通过上述的例子,应该明白unix中aio是如何使用的了。call_back方式比较方便,程序不用关注IO操作的返回情况。