现在的位置: 首页 > 综合 > 正文

poll设备方法

2017年08月25日 ⁄ 综合 ⁄ 共 2279字 ⁄ 字号 评论关闭

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系统调用,若不使用的话直接读的话,在读的回调函数中,仍然要使用阻塞型字符设备驱动技术,因为在设备驱动的设计中一般默认是使用阻塞型设备驱动的。

抱歉!评论已关闭.