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