poll设备方法----
系统调用----用户空间 驱动----------内核空间
open open
close release
read read
write write
loctl loctl
lseek llseek
select poll
select系统调用用于多路监控,当没有一个文件满足要求时,select将阻塞调用进程。
int select(
int maxfd,文件描述符的范围,比待测的最大文件描述符大1
fd_set *readfds,被读监控的文件描述符
fd_set *writefds,被写监控的文件描述符
fe_set *exceptfds,被异常监控的文件描述符
const struct timeval *timeout定时器
)
timeout取不同的值,该调用有不同的表现:
timeout=0,不管是否有文件满足要求,都立刻返回,无文件满足要求返回0,有文件满足要求返回一个正值。
timeout为NULL,select将阻塞进程,直到某个文件满足要求。
timeout为正整数,就是等待的最长时间,即select在timeout时间内阻塞进程。
select调用返回时,返回值有如下情况:
1--正常情况下返回满足要求的文件描述符个数。
2--经过了timeout等待后仍无文件满足要求,返回值为0.
3--如果select被某个信号中断,它将返回-1并设置errno为EINTR。
4--如果出错,返回-1,并设置相应的errno。
select系统调用---使用方法
1--将要监控的文件添加到文件描述符集
2--调用select开始监控
3--判断文件是否发生变化。
系统提供了4个宏对描述符集进行操作---
#include <sys/select.h>
void FD_SET(int fd,fd_set *fdset)
void FD_CLR(int fd,fd_set *fdset)
void FD_ZERO(fd_set *fdset)
void FD_ISSET(int fd,fd_set *fdset)
宏FD_SET将文件描述符fd添加到文件描述符集fdset中。
宏FD_CLR将文件描述符集fdset中清除文件描述符fd。
宏FD_ZERO清空文件描述符集fdset
在调用select后使用FD_ISSET来检测文件描述符集fdset中的文件fd发生了变化。
实例---
FD_ZERO(&fds);
FD_SET(fd1,&fds);
FD_SET(fd2,&fds);
maxfdp=fd1+1;描述符最大值加1,假设fd1>fd2
switch(select(maxfdp,&fds,NULL,NULL,&timeout))
case -1:exit(-1);break;select错误,退出程序
case 0:break;
default:
if(FD_ISSET(fd1,&fds))测试fd1是否可读。
应用程序常常使用select系统调用,它可能会阻塞进程。这个调用由驱动的poll方法实现,原型为:
unsigned int (*poll) (struct file *filp,poll_table *wait)
poll设备方法负责完成:
1使用poll_wait将等待队列添加到poll_table中。
2返回描述设备是否可读或可写的掩码。
位掩码-----
POLLIN-----设备可读
POLLRDNORM-----数据可读
POLLOUT------设备可写
POLLWRNORM---数据可写
设备可读通常返回-----(POLLIN|POLLRDNORM)
设备可写通常返回-----(POLLOUT|POLLWRNORM)
范例------------
static unsigned int mem_poll(struct file *filp,poll_table *wait)
{
struct scull_pipe *dev=filp->private_data;
unsigned int mask=0;
把等待队列添加到poll_table
poll_wait(filp,&dev->inq,wait);
返回掩码
if(有数据可读)
mask=POLLIN|POLLRDNORM;设备可读
return mask;
}
工作原理------
poll方法只是做了一个登记,真正的阻塞发生在select.c中的do_select函数。
select系统调用是由do_select函数完成的。
poll设备方法对应select系统调用,多路监控,比如,可监控文件是否可读,若可读就直接读,不可读则阻塞,或返回。这样就不用在read的回调函数中使用等待队列设置阻塞型设备驱动了。但要求应用程序使用select系统调用,若不使用的话直接读的话,在读的回调函数中,仍然要使用阻塞型字符设备驱动技术,因为在设备驱动的设计中一般默认是使用阻塞型设备驱动的。