欢迎访问电子工程网!   登录 | 免费注册 ]   

yd2763132的个人空间 http://www.eechina.com/space-uid-36266.html [收藏] [复制] [分享] [RSS]

博客

信号和AIO

已有 330 次阅读2011-5-13 21:58 |个人分类:linux

异步阻塞IO:阻塞通知非阻塞io,即io操作发出后不阻塞IO操作,将通知阻塞,直到采用select查询后才获得操作结果;
?? 异步非阻塞IO:即io操作发出后不阻塞IO操作也不阻塞通知,当操作完成后内核通过信号或回调方式主动通知调用进程,而不需要等待调用者主动进行查询。
?? 在异步IO操作中,当IO资源可用时驱动释放相应的信号给调用进程;当调用者捕获到信号后执行相关的信号处理函数;对于应用程序需通过fcntl(fd,F_SETOWN,getpid())将该进程设定为操作资源(文件)的属主以确定信号的接受对象,通过fcntl(fd,F_SETFL,FASYNC)设置FASYNC 调用驱动的fasync函数;待资源可使用时kill_fasync函数释放信号给调用者。
?? AIO 的基本思想是允许进程发起很多 I/O 操作,而不用阻塞或等待任何操作完成。稍后或在接收到 I/O 操作完成的通知时,进程就可以检索 I/O 操作的结果;对于一系列的IO操作是使用lio_list函数发起的,先定义一个aiocb的指针数组后于之即可发起;AIO可以使用信号或回调函数作为资源可用通知。
struct sigaction
??{
??__sighandler_t sa_handler; //信号处理函数地址 *阻塞的意思是延迟相应信号
??unsigned long sa_flags; //信号的处理标志:
??//SA_NODEFER表示内核不阻塞信号,一般为阻塞信号
??//SA_RESETHAND:表示调用信号处理函数重置为缺省态
??//SA_SIGINFO:表示处理函数有三个参数;void (*_sa_sigaction)(int,struct siginfo *,void *)因为对于应用层而言处理函数为 union {__sighandler_t _sa_handler; void (*_sa_sigaction)(int, struct siginfo *, void *);} _u;
??__sigrestore_t sa_restorer; //保存地址
??sigset_t sa_mask; //指定哪些信号被阻塞,一般默认为当前信号被阻塞

};
??
struct aiocb {
?? int aio_fildes; //aio文件描述符
?? int aio_lio_opcode;//进行批量IO操作时有效,读写类型
?? volatile void *aio_buf;//数据缓冲
?? size_t aio_nbytes; //数据缓冲长度
?? int aio_reqprio;//信号优先级
?? struct sigevent aio_sigevent; //aio结束后该执行的操作
?? /* Internal fields */
};
??
struct sigevent {
??union sigev_value{int sival_int;void *sival_ptr;}
??//信号传递值,即信号传递为处理函数的信息;
?? 若函数为独参时为信号值
?? 若为三个参数时则将包含aiocb结构体的siginfo _t传递给函数以完成AIO的异步读写。
??int sigev_signo; //信号值(类型)
??int sigev_notify; //通知模式SIGEV_SIGNAL为信号,SIGEV_THREAD为回调函数
??union {
?? int _pad[SIGEV_PAD_SIZE];
?? int _tid; //使用宏定义sigev_notify_thread_id 线程ID号
?? struct {
?? void (*_function)(sigval_t); //使用宏定义sigev_notify_function为线程回调函数
?? void *_attribute; //使用宏定义sigev_notify_attributes为线程属性
?? } _sigev_thread;
?? } _sigev_un;
};
??
使用范例:


//初始化信号                                                                                


sig_act.sa_mask=0;                                                 


sig_act.sa_flags= SA_SIGINFO; //信号传递aiobc    //--------------------------------------------------


使用3参数;                                                                                          


sig_act. sa_sigaction=fun;//信号处理函数                  //---------------------------------------------------                        


                                                                            


//初始化aiocb结构


my_aiocb. aio_fildes=fd;


my_aiocb. aio_buf=***;


my_aiocb. aio_nbytes=N;


my_aiocb. aio_offset=next_offset;


//表示下一个操作从上一个操作结束处开始


//AIO请求于与信号处理函数链接                               //AIO请求于与回调线程处理函数链接


my_aiocb. aio_sigevent. sigev_notify=SIGEV_SIGNAL;     my_aiocb. aio_sigevent. sigev_notify=SIGEV_THREAD;


//表示以信号作通知                                          //表示以回调线程作通知


my_aiocb. aio_sigevent. sigev_signo=SIGIO;        my_aiocb. aio_sigevent. sigev_notify_function=fun1;//回调函数


                                                                        my_aiocb. aio_sigevent. sigev_notify_attributes=NULL;//属性不使用


my_aiocb. aio_sigevent. sival_ptr=&my_aiocb;      my_aiocb. aio_sigevent. sival_ptr=&my_aiocb;


 


//捕获信号


sigaction(SIGIO,&sig_act,NULL);                      //--------------------------------------------------               


 


//信号处理函数                                                      // 回调函数


void funint signo,siginfo_t *info,void *context     void fun1sigval_t sigval


{-----------------------------p=info->si_value.sival_ptr;      {-----------------------------p=sigval.sival_ptr;


//获得aiobc地址                                                           //获得aiobc地址


}     ?                                                                        }


路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)

facelist

您需要登录后才可以评论 登录 | 立即注册

回顶部