生活随笔
收集整理的這篇文章主要介紹了
poll接口
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
如果設(shè)備被配置成阻塞式操作,即當(dāng)設(shè)備執(zhí)行I/O操作時(shí)如果不能獲得數(shù)據(jù)將阻塞,直到獲得數(shù)據(jù)。應(yīng)用層可以使用select函數(shù)查詢?cè)O(shè)備當(dāng)前的狀態(tài),以便用戶程序獲知是否能對(duì)設(shè)備進(jìn)行非阻塞的訪問(wèn)。使用select函數(shù)需要在設(shè)備驅(qū)動(dòng)程序中添加file_operations->poll接口支持。一個(gè)典型的字符驅(qū)動(dòng)程序的file_operations->poll函數(shù)的實(shí)現(xiàn)如下:
static?unsigned?int?my_poll(struct?file?*file,?struct?poll_table_struct?*wait) ?{ ?????unsigned?int?mask?=?0; ?????poll_wait(file,?&?outq,?wait);//把當(dāng)前進(jìn)程添加到等待列表 ?????if?(0?!=?bta->read_count)//如果有數(shù)據(jù) ?????????mask?|=?(POLLIN?|?POLLRDNORM); ?????return?mask; ?} ?
驅(qū)動(dòng)程序中的poll函數(shù)返回的標(biāo)志如下:
#define?POLLIN????????????1?//設(shè)備可以無(wú)阻塞地讀取 ?#define?POLLPRI???????2//可以無(wú)阻塞地讀取高優(yōu)先級(jí)數(shù)據(jù)(帶外數(shù)據(jù)) ?#define?POLLOUT???????4//設(shè)備可以無(wú)阻塞地寫入 ?#define?POLLERR???????8//設(shè)備發(fā)生錯(cuò)誤 ?#define?POLLHUP???????16//當(dāng)讀取設(shè)備的進(jìn)程到達(dá)文件尾部 ?#define?POLLNVAL??????????32?//請(qǐng)求無(wú)效 ?#define?POLLRDNORM????64//常規(guī)數(shù)據(jù)已經(jīng)就緒 ?#define?POLLWRNORM??POLLOUT ?#define?POLLRDBAND????128//可以從設(shè)備讀帶外數(shù)據(jù) ?#define?POLLWRBAND????256//可以向設(shè)備寫帶外數(shù)據(jù) ?#define?POLLMSG???????0x0400 ?#define?POLLREMOVE???0x1000 ?#define?POLLRDHUP????0x2000 ?
應(yīng)用層多路I/O選擇函數(shù)select的原型如下:
int?select(int?numfds,?fd_set?*readfds,?fd_set?
*writefds,?fd_set?*exceptfds,?struct?timeval?*timeout);?
其中readfds、writefds、exceptfds分別是被select函數(shù)監(jiān)視的讀、寫和異常處理的文件描述符集合,numfds的值是需要檢查的號(hào)碼最高的文件描述符加1。timeout參數(shù)是一個(gè)指向struct timeval類型的指針,它可以使select函數(shù)在等待timeout時(shí)間后若沒(méi)有文件描述符準(zhǔn)備好則返回。文件描述符集常用函數(shù)接口如下:
FD_ZERO(fd_set *set)//清除一個(gè)文件描述符集;
FD_SET(int fd,fd_set *set)//將文件描述符fd加入文件描述符集中;
FD_CLR(int fd,fd_set *set)//將文件描述符fd從文件描述符集中清除;
FD_ISSET(int fd,fd_set *set)//判斷文件描述符fd是否被置位。
例1.7? poll接口驅(qū)動(dòng)程序示例
代碼見(jiàn)光盤\src\1drivermodel\1-7poll。核心代碼如下所示:
FD_ZERO(fd_set?*set)//清除一個(gè)文件描述符集;? ?FD_SET(int?fd,fd_set?*set)//將文件描述符fd加入文件描述符集中;? ?FD_CLR(int?fd,fd_set?*set)//將文件描述符fd從文件描述符集中清除;? ?FD_ISSET(int?fd,fd_set?*set)//判斷文件描述符fd是否被置位。 ?
例1.7? poll接口驅(qū)動(dòng)程序示例
代碼見(jiàn)光盤\src\1drivermodel\1-7poll。核心代碼如下所示:
ssize_t?simple_read(struct?file?*filp,?char?__user?*buf,?size_t?count,loff_t?*f_pos) ?{ ?????//printk("wait_event_interruptible?before\n"); ?????wait_event_interruptible(read_queue,?simple_flag); ?????//printk("wait_event_interruptible?after\n"); ?????if?(copy_to_user(buf,demoBuffer,count)) ?????{ ?????????count=-EFAULT; ?????} ?????return?count; ?} ?ssize_t?simple_write(struct?file?*filp,?const?char?__user?*buf,?size_t?count,loff_t?*f_pos) ?{ ?????if?(copy_from_user(demoBuffer,?buf,?count)) ?????{ ?????????count?=?-EFAULT; ?????????goto?out; ?????} ?????simple_flag=1; ?????wake_up(&read_queue); ?out: ?????return?count; ?} ?//poll接口實(shí)現(xiàn) ?unsigned?int?simple_poll(struct?file?*?file,?poll_table?*?pt) ?{ ?????unsigned?int?mask?=?POLLIN?|?POLLRDNORM; ?????poll_wait(file,?&read_queue,?pt); ?????return?mask; ?} ?struct?file_operations?simple_fops?=?{ ?????.owner?=????THIS_MODULE, ?????.poll?=?????simple_poll, ?????.read?=?????simple_read, ?????.write=?????simple_write, ?????.open?=?????simple_open, ?????.release?=??simple_release, ?}; ?
應(yīng)用程序參考代碼如下:
int?fd; ?void?*readthread(void?*arg)//讀數(shù)據(jù)線程 ?{ ?????char?data[256]; ?????fd_set?rfds;?//讀描述符集合 ?????fd_set?wfds;?//寫描述符集合 ?????int?retval=0; ?????while(1) ?????{ ?????????FD_ZERO(&rfds); ??????????FD_SET(fd,?&rfds); ?????????select(fd+1,?&rfds,?&wfds,?NULL,?NULL);?//多路選擇 ?????????if(FD_ISSET(fd,?&rfds)) ?????????{ ?????????????retval=read(fd,data,3); ?????????????if(retval==-1) ?????????????{ ?????????????????perror("read?error\n"); ?????????????????exit(-1); ?????????????} ?????????????data[retval]=0; ?????????????printf("read?successfully:%s\n",data); ?????????} ?????} ?????return?(void?*)0; ?}? ?void?main() ?{ ?????int?i; ?????int?retval; ?????fd=open("/dev/fgj",O_RDWR); ?????if(fd==-1) ?????{ ?????????perror("error?open\n"); ?????????exit(-1); ?????} ?????printf("open?/dev/fgj?successfully\n"); ?????pthread_t?tid; ?????pthread_create(&tid,?NULL,?readthread,?NULL);//創(chuàng)建讀線程 ?????while(1) ?????{ ?????????retval=write(fd,"fgj",3);//主線程負(fù)責(zé)寫數(shù)據(jù) ?????????if(retval==-1) ?????????{ ?????????????perror("write?error\n"); ?????????????exit(-1); ?????????} ?????} ?????close(fd); ?} ?
本例運(yùn)行結(jié)果如下:
[root@urbetter?/home]#?insmod?demo.ko ?[root@urbetter?/home]#?mknod?/dev/fgj?c?224?0 ?[root@urbetter?/home]#?./test ?read?successfully:fgj ?read?successfully:fgj ?read?successfully:fgj ?read?successfully:fgj ?... ?
總結(jié)
以上是生活随笔為你收集整理的poll接口的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。