同步阻塞io模型
异步非阻塞io模型
AIO编程方法
对象
#include <aiocb.h>
struct aiocb {
/* The order of these fields is implementation-dependent */
int aio_fildes; /* 文件句柄*/
off_t aio_offset; /* File offset */
volatile void *aio_buf; /* 数据缓冲区 */
size_t aio_nbytes; /* 读写数量 */
int aio_reqprio; /* Request priority */
struct sigevent aio_sigevent; /* 约定回调函数 */
int aio_lio_opcode; /* 操作码,操作方向 LIO_READ LIO_WRITE*/
/* Various implementation-internal fields not shown */
};
AIO_READ AIO_WRITE
int aio_read(struct aiocb *aiobp);
函数在请求进行排队候立刻返回,执行成功返回0,出错返回-1,并设置error的值
int aio_error(struct aiocb *aiobp) 该函数用来确认请求的状态
返回值:EINPROGRESS 请求尚未完成
ECANCELLED 请求被应用程序取消了
-1 发生错误 可查询error 0 说明完成了当前操作
ssize_t aio_return(struct aiocb *aiobp) 获得返回状态
如果设置回调函数需要设置如下:
//结构体定义
struct sigevent {
int sigev_notify; /* Notification method */
int sigev_signo; /* Notification signal */
union sigval sigev_value; /* Data passed with
notification */
void (*sigev_notify_function) (union sigval);
/* Function used for thread
notification (SIGEV_THREAD) */
void *sigev_notify_attributes;
/* Attributes for notification thread
(SIGEV_THREAD) */
pid_t sigev_notify_thread_id;
/* ID of thread to signal (SIGEV_THREAD_ID) */
};
//--------------------------------赋值方式-----------------------------------------
rd.aio_sigevent.sigev_notify = SIGEV_THREAD; //使用线程回调通知
rd.aio_sigevent.sigev_notify_function = aio_handler;//设置回调函数
//回调函数格式 void xxxxx(sigval_t sigval)....
rd.aio_sigevent.sigev_notify_attributes = NULL;//使用默认属性
rd.aio_sigevent.sigev_value.sival_ptr = &rd; //在aiocd控制模块中加入对自己的引用
简单例子:
#include "stdio.h"
#include "errno.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <aio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
//#include <aiocb.h>
#define BUFF_SIZE 1024
int main(int argc,char *argv[])
{
int file = 0;
struct aiocb aiostr;
char * buf;
buf = (char *)malloc(BUFF_SIZE+1);
memset(buf,'\0',sizeof(buf));
bzero(&aiostr,sizeof(aiostr));
if(argc < 2)
{
printf("please input file path!\n");
}
file = open(argv[1],O_RDONLY);
if(file<0)
{
perror("open");
exit(0);
}
aiostr.aio_fildes = file;
aiostr.aio_buf = buf;
aiostr.aio_nbytes = BUFF_SIZE;
aio_read(&aiostr);
while(aio_error(&aiostr)== EINPROGRESS){
printf("file reading!\n");
usleep(1);
}
ssize_t ret = aio_return(&aiostr);
close(file);
//printf("file size is:%d\n",ret);
printf("%s\n",buf);
free(buf);
return 0;
}
int aio_susupend(const atruct aiocb * const cblist[],int n,const struct timespec * timeout)
使当前进程挂起,直到它注册的异步事件全部完成为止
第一个参数:保存aiocb块地址的数据 第二个参数:向cblist中放入的个数 第三个参数:超时时间 NULL无限等待
int lio_listio(int mod ,struct aiocb * list[],int nent,struct sigevent *sig);
第一个参数:LIO_WAIT:阻塞直到所有io完成操作 LIO_NOWAIT :将aiocb挂入队列直接返回 完成后返回信号
复杂例子,批量处理加回调
#include "stdio.h"
#include "errno.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <aio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
//#include <aiocb.h>
#define BUFF_SIZE 128
#define MODE S_IRWXU | S_IXGRP | S_IROTH | S_IXOTH
void aio_call_handler(sigval_t sigval){
struct aiocb * aio = (struct aiocb *)(sigval.sival_ptr);
if(aio_error(aio)==0){
ssize_t ret = aio_return(aio);
if(ret >= 0){
printf("文件写入成功\n");
close(aio->aio_fildes);
}
}
}
int main(int argc,char *argv[])
{
int file[10] = {0};
struct aiocb * aiostr[10];
struct sigevent rd;
char * buf;
char name[10] = {0};
buf = (char *)malloc(BUFF_SIZE+1);
memset(buf,'\0',sizeof(buf));
strcat(buf,"hello,world!");
for (int i = 0; i < 10; ++i)
{
sprintf(name,"haha%d",i);
if((file[i] = open(name,O_RDWR|O_CREAT))==-1)
{printf("open faile\n");
exit(0);}
aiostr[i] = (struct aiocb*)malloc(sizeof(struct aiocb));
bzero(aiostr[i],sizeof(struct aiocb));
aiostr[i]->aio_fildes = file[i];
aiostr[i]->aio_buf = buf;
aiostr[i]->aio_nbytes = BUFF_SIZE;
aiostr[i]->aio_lio_opcode = LIO_WRITE;
aiostr[i]->aio_sigevent.sigev_notify = SIGEV_THREAD;
aiostr[i]->aio_sigevent.sigev_notify_function = aio_call_handler;
aiostr[i]->aio_sigevent.sigev_notify_attributes = NULL;
aiostr[i]->aio_sigevent.sigev_value.sival_ptr = aiostr[i];
}
lio_listio(LIO_NOWAIT,aiostr,10,NULL);
int i = 0;
while(i<10){
sleep(1);
i++;
}
free(buf);
for(int a = 0;a<10;a++)
{
free(aiostr[a]);
}
return 0;
}