poll机制分析
更多文档:http://pan.baidu.com/s/1sjzzlDF
linux poll/select用法及在字符驱动中的简单实现
1.poll和select
使用非阻塞I/O 的应用程序常常使用poll, select, 和epoll 系统调用. poll, select 和epoll 本质上有相同的功能: 每个都允许一个进程来决定它是否可读或者可写一个或多个文件而不阻塞。 这些调用也可阻塞进程直到任何一个给定集合的文件描述符可用来读或写。因此, 它们常常用在必须使用多输入输出流的应用程序, 而不必粘连在它们任何一个上。相同的功能常常由多个函数提供, 因为2 个是由不同的团队在几乎相同时间完成的:select 在BSD Unix 中引入, 而poll 是System V 的解决方案。epoll 调用添加在2.5.45, 作为使查询函数扩展到几千个文件描述符的方法。
1.1 select
int select(int nfds,
fd_set *readfds,
fd_set *writefds,
fd_set *exceptfds,
struct timeval *timeout);
nfds is the highest-numbered file descriptor in any of the three sets, plus 1;
fd_set表示文件描述符集合的一个结构体,操作这个结构体,有一些特定的函数:
void FD_CLR(int fd, fd_set *set); //把文件描述符fd, 从集合里清掉。
int FD_ISSET(int fd, fd_set *set); //判断一个文件描述符fd, 是否在集合set里
void FD_SET(int fd, fd_set *set); //把文件描述符fd,加到集合set中去
void FD_ZERO(fd_set *set); //把文件描述符集合set清空。
Select 返回值:
On success, select() eturn the number of file descriptors contained in the three returned descriptor sets (that is, the total number of bits that are set in readfds, writefds, exceptfds) which may be zero if the timeout expires before anything interesting happens. On error, -1 is returned, and errno is set appropriately; the sets and timeout become undefined, so do not rely on their contents after an error。
用法实例:参见代码。
1.2 poll
poll的作用与select类似,it waits for one of a set of file descriptors to become ready to perform I/O。原理如下:
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
每个要监听的文件描述符对应一个struct pollfd结构,参数fds指向所有要监听的文件描述符对应结构体struct pollfd的数组;参数nfds 表示struct pollfd结构的数目(亦即是要监听的文件描述符的个数);timeout是超时时间,单位为milliseconds(指定一个负数表示一直阻塞)。
Struct pollfd 结构体:
Struct pollfd {
int fd ; /* file descriptor */
short events; /* requested events */
short revents; /* returned events*/
};
要监听的事件(events)和返回的事件(revents),是由一些位掩码组成的,定义在<linux/poll.h>中:
POLLIN
如果设备可被不阻塞地读, 这个位必须设置.
POLLRDNORM
这个位必须设置, 如果"正常"数据可用来读. 一个可读的设备返回( POLLIN|POLLRDNORM ).
POLLRDBAND
这个位指示带外数据可用来从设备中读取. 当前只用在Linux 内核的一个地方( DECnet 代码)并且通常对设备驱动不可用.
POLLPRI
高优先级数据(带外)可不阻塞地读取. 这个位使select 报告在文件上遇到一个异常情况, 因为selct 报告带外数据作为一个异常情况.
POLLHUP
当读这个设备的进程见到文件尾, 驱动必须设置POLLUP(hang-up). 一个调用select 的进程被告知设备是可读的, 如同selcet 功能所规定的.
POLLERR
一个错误情况已在设备上发生. 当调用poll, 设备被报告位可读可写, 因为读写都返回一个错误码而不阻塞.
POLLOUT
这个位在返回值中设置, 如果设备可被写入而不阻塞.
POLLWRNORM
这个位和POLLOUT 有相同的含义, 并且有时它确实是相同的数. 一个可写的设备返回( POLLOUT|POLLWRNORM).
POLLWRBAND
如同POLLRDBAND , 这个位意思是带有零优先级的数据可写入设备. 只有poll 的数据报实现使用这个位, 因为一个数据报看传送带外数据.
应当重复一下POLLRDBAND 和POLLWRBAND 仅仅对关联到socket 的文件描述符有意义: 通常设备驱动不使用这些标志.
poll 返回值:
On success, a positive number is returned; this is the number of structures which have nonzero revents fields (in other words, those descriptors with events or errors reported)。A value of 0 indicates that the call timed out and no file descriptors were ready. On error, -1 is returned, and errno is set appropriately.
用法实例:参见代码。
2. 驱动实现
其实select(或pselect)、poll(或epoll,ppoll)都是通过poll系统调用进入内核的。支持任何一个这些调用都需要来自设备驱动的支持。这个支持(对所有3 个调用)由驱动的poll 方法调用。这个方法由下列的原型:
unsigned int (*poll) (struct file *filp, poll_table *wait);
无论何时用户空间程序进行一个poll, select, 或者epoll 系统调用,涉及一个和驱动相关的文件描述符时,这个驱动方法被调用。
在驱动中,poll方法的实现,只需要两步:
⑴在一个或多个可指示查询状态变化的等待队列上调用poll_wait. 如果没有文件描述符可用作I/O, 内核使这个进程在等待队列上等待所有的传递给系统调用的文件描述符。
poll_wait的原型是:
void poll_wait (struct file *, wait_queue_head_t *, poll_table *);
在调用这个函数时,我们只需要关注第二个参数,另外两个参数和poll方法相同。第二个参数就是我们驱动里定义的等待队列指针。
⑵ 根据条件返回一个事件位掩码。(见上文)
用法实现:参见代码。
注意:
驱动里调用poll_wait是不会在阻塞的,真正的“轮询”是通过虚拟文件系统层的sys_poll来实现的。
拓展(内核poll机制大致流程, 可以阅读内核相关代码fs/select.c):
⑴poll > sys_poll > do_sys_poll > poll_initwait,poll_initwait函数注册一下回调函数__pollwait,它就是我们的驱动程序执行poll_wait时,真正被调用的函数。
⑵接下来执行file->f_op->poll,即我们驱动程序里自己实现的poll函数。它会调用poll_wait把自己挂入某个队列,这个队列也是我们的驱动自己定义的;它还判断一下设备是否就绪。
⑶如果设备未就绪,do_sys_poll里会让进程休眠一定时间
⑷进程被唤醒的条件有2:一是上面说的“一定时间”到了,二是被驱动程序唤醒。驱动程序发现条件就绪时,就把“某个队列”上挂着的进程唤醒,这个队列,就是前面通过poll_wait把本进程挂过去的队列。
⑸如果驱动程序没有去唤醒进程,那么schedule_timeout(__timeou)超时后,会重复⑵、⑶动作,直到应用程序的poll调用传入的时间到达。
poll机制分析的更多相关文章
- 字符设备驱动笔记——poll机制分析(七)
poll机制分析 所有的系统调用,基于都可以在它的名字前加上“sys_”前缀,这就是它在内核中对应的函数.比如系统调用open.read.write.poll,与之对应的内核函数为:sys_open. ...
- Linux通信之poll机制分析
poll机制分析 韦东山 2009.12.10 所有的系统调用,基于都可以在它的名字前加上“sys_”前缀,这就是它在内核中对应的函数.比如系统调用open.read.write.poll,与之对应的 ...
- poll机制分析[转]
所有的系统调用,基于都可以在它的名字前加上"sys_"前缀,这就是它在内核中对应的函数.比如系统调用open.read.write.poll,与之对应的内核函数为:sys_open ...
- Linux之poll机制分析
应用程序访问1个设备文件时可用阻塞/非阻塞方式.如果是使用阻塞方式,则直接调用open().read().write(),但是在驱动程序层会判断是否可读/可写,如果不可读/不可写,则将当前进程休眠,直 ...
- 字符驱动程序之——poll机制
关于这个韦老师给了一个简单的参考文档: poll机制分析 韦东山 2009.12.10 所有的系统调用,基本都可以在它的名字前加上“sys_”前缀,这就是它在内核中对应的函数.比如系统调用open.r ...
- poll系统调用的内核态实现机制分析
版权所有,转载请标明出处 All right reserved,Copyright by 徐行而至 浅唱而归 前面已经比较详尽的分析了系统调用引发的内核执行过程,本文将继续分析一下linux2.6 ...
- poll机制
使用POLL机制代替linux输入子系统(input subsystem)之按键输入和LED控制中的异步通知,实现同样的效果. 1.代码 只简单修改input_subsys_test.c, input ...
- 8.中断按键驱动程序之poll机制
本节继续在上一节中断按键程序里改进,添加poll机制. 那么我们为什么还需要poll机制呢.之前的测试程序是这样: ) { read(fd, &key_val, ); printf(" ...
- 字符设备驱动(六)按键poll机制
title: 字符设备驱动(六)按键poll机制 tags: linux date: 2018-11-23 18:57:40 toc: true --- 字符设备驱动(六)按键poll机制 引入 在字 ...
随机推荐
- CenotOS ip a
- SQL Server文本和图像函数
文本和图像函数 1.查找特定字符串PATINDEX 语法与字符串的patindex一样. 2.获取文本指针TEXTPTR SQLServer在存储文本类型(ntext.text)和图像数据类型(ima ...
- MVC如何配置才能访问静态页面
默认在Views文件外的静态页面可以访问,若要访问Views里的静态页面则需要修改View文件夹中的web.config: <system.webServer> <handlers& ...
- nginx配置 首页不显示 index.html首页是显示域名
原状况如下: 访问:www.test.com 敲回车后浏览器中自动跳转致: www.test.com/index.html 公司新需求如下: 访问:www.test.com 敲回车后浏览器中url不变 ...
- 关于诺顿身份安全2013独立版(Norton Identity Safe)
现在身份安全这货好像从诺顿的套装当中独立出来了,出了中文版.其实诺顿的Web信誉做得还是不错的,当然天朝不要有太大期望.只是公认的做web信誉做得最好的应该就是趋势科技和诺顿,所以诺顿的身份安全也许还 ...
- MetaQ安装部署文档
一.MetaQ安装部署情况: 地点 IP Broker ID Master/Slave Slave ID:Group 合肥 192.168.52.23 Slave 1:meta-slave-group ...
- How Tomcat Works(十三)
本文分析tomcat容器的安全管理,servlet技术支持通过配置部署描述器(web.xml文件)来对受限内容进行访问控制:servlet容器是通过一个名为验证器的阀来支持安全限制的,当servlet ...
- SQL2005/8数据库提示单个用户无法操作的解决方法
原因分析: 是操作数据库的用户被锁定了,思路是通过查找目标用户,将其解锁即可,可是这样太麻烦了. 解决办法执行如下sql: USE master; GO DECLARE @SQL VARCHAR( ...
- Windows7部署WordPress傻瓜式教程(IIS7.5+MySQL+PHP+WordPress)
http://www.cnblogs.com/vengen/archive/2010/01/01/WordPressInstall.html
- Oracle-11g-R2 RAC 环境下 GPnP Profile 文件
GPnP Profile 文件的作用: GPnP Profile 文件是一个保存于 $GRID_HOME/gpnp/<hostname>/profiles/peer 目录下的小型 XML ...