Linux development --AIO design framework

Disclaimer: This article is a blogger original article, follow the CC 4.0 BY-SA copyright agreement, reproduced, please attach the original source link and this statement.
This link: https://blog.csdn.net/qq_25490573/article/details/102545615

Synchronous blocking io model

Asynchronous non-blocking io model

AIO Programming

Objects

 #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);

         The function returns the request queue waiting immediately executed successfully returns 0, -1 error, set error value and

int aio_error (struct aiocb * aiobp) This function is used to confirm the status of the request

         Return Value: EINPROGRESS request has not yet completed

                     ECANCELLED request was canceled by the application

                     -1 error occurs can check error 0 Complete the current operation

ssize_t aio_return (struct aiocb * aiobp) get the return status

          If the callback function needs to be set as follows:

          

//结构体定义    
   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控制模块中加入对自己的引用

A simple example:

#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) 

              The current process is suspended until it is registered asynchronous events completed so far

              The first parameter: the block address save data aiocb second argument: the number cblist into the third parameter: NULL timeout wait indefinitely

int lio_listio(int mod ,struct aiocb * list[],int nent,struct sigevent *sig);

               The first parameter: LIO_WAIT: io finished until all the blocking LIO_NOWAIT: return signal returned directly linked into the queue is completed aiocb

Complex example, batch processing plus callback

#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;

}

 

Guess you like

Origin blog.csdn.net/qq_25490573/article/details/102545615