Linux开发——AIO设计框架

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_25490573/article/details/102545615

同步阻塞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;

}

猜你喜欢

转载自blog.csdn.net/qq_25490573/article/details/102545615
今日推荐