2012年(1008)
分类:
2012-08-01 11:05:44
原文地址:Poll设备操作 作者:luozhiyong131
Select系统调用用于多路监控,当没有一个文件满足要求时,select将阻塞调用进程。
int select(int maxfd, fd_set *readfds, fd_set *writefds, fe_set *exceptfds, const struct timeval *timeout)
参数
Maxfd: 文件描述符的范围,比待检测的最大文件描述符大1
Readfds: 被读监控的文件描述符集
Writefds: 被写监控的文件描述符集
Exceptfds: 被异常监控的文件描述符集;
Timeout: 定时器
Timeout取不同的值,该调用有不同的表现:
Timeout值为0,不管是否有文件满足要求,都立刻返回,无文件满足要求返回0,有文件满足要求返回一个正值。
Timeout为NULL,select将阻塞进程,直到某个文件满足要求
Timeout值为正整数,就是等待的最长时间,即select在timeout时间内阻塞进程。
Select调用返回时,返回值有如下情况:
1.正常情况下返回满足要求的文件描述符个数;
2.经过了timeout等待后仍无文件满足要求,返回值为0;
3.如果select被某个信号中断,它将返回-1并设置errno为EINTR。
4.如果出错,返回-1并设置相应的errno。
系统提供了个宏对描述符集进行操作:
#include
void FD_SET(int fd, fd_set *fdset) 宏FD_SET将文件描述符fd添加到文件描述符集fdset中;
void FD_CLR(int fd, fd_set *fdset) 宏FD_CLR从文件描述符集fdset中清除文件描述符fd;
void FD_ZERO(fd_set *fdset) 宏FD_ZERO清空文件描述符集fdset;
void FD_ISSET(int fd, fd_set *fdset) 在调用select后使用FD_ISSET来检测文件描述符集fdset中的文件fd发生了变化。
Select系统调用(使用方法)
FD_ZERO(&fds); //清空集合
FD_SET(fd1,&fds); //设置描述符
FD_SET(fd2,&fds); //设置描述符
maxfdp=fd1+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是否可读
Poll方法
应用程序常常使用select系统调用,它可能会阻塞进程。这个调用由驱动的poll 方法实现,原型为: unsigned int (*poll)(struct file *filp,poll_table *wait)
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_wait(filp,&dev->inq,wait);
/*返回掩码*/
if (有数据可读)
mask = POLLIN |POLLRDNORM;/*设备可读*/
return mask;
}
实例代码:字符设备驱动的Poll函数 Poll型设备驱动.rar