本文共 1165 字,大约阅读时间需要 3 分钟。
在设备驱动中使用异步通知可以使得对设备的访问在进行时,由驱动程序主动通知应用程序进行访问,这样,使用无阻塞IO的应用程序无需轮需设备是否可访问。而阻塞访问也可被类似“中断”的异步通知所取代。
linux中的异步通知是通过信号来实现的。
在用户程序中,为了捕获信号,可以使用signal()
void (*signal (int signum,void(*handler))(int))(int)
第一个参数指定信号的值,第二个参数指定前面信号值的处理函数。这个函数是在应用层使用
在设备驱动中异步通知编程比较简单,主要用到一项数据结构和两个函数。数据结构时fasync_struct结构体,
处理FASYNC标志变更的函数
int fasync_helper(int fd,struct file *filp ,int mode,struct fasync_struct **fa)
释放信号用的函数
void kill_fasync(struct fasync_struct **fa,int sig,int band);
static int xxx_fasync(int fd,struct file *filp,int mode){ struct xxx_dev *dev =filp->private_data; return fasync_helper(fd,filp,mode,&dev->async_queue) }
在设备被正确写入之后,它变得可读,这个时候驱动应释放SIGIO信号以便应用程序捕获
static ssize_t xxx_write(.....){ //写入成功后。释放信号 if(dev->async_queue) kill_fasync(&dev->async_queue,SIGIO,POLL_IN)}
应用程序可以这样写
void input_handler(int signum){ printf("recive from %d\n",signum); }int main(){ int fd ,oflags; fd=open("/dev/global",O_RDWR,S_IRUSR | S_IWUSR); if(fd != -1){ //启动信号机制 signal(SIGIO,input_handler); fcntl(fd,F_SETOWN,getpid()); oflags = fcntl(fd,F_GETFL); fcntl(fd,F_SETFL,oflags | FASYNC); while(1) { sleep(1000); }}}
运行程序后,每当写入数据后,都会触发input_handler()这个函数
转载地址:http://wwvqb.baihongyu.com/