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