poll函数是Unix提供的一个系统调用函数,可以同时查询多个文件描述符的状态,类似功能的函数还有select,它们都使用了称之为I/O multiplexing技术,先构造一张有关描述符的列表,然后调用一个函数,直到这些描述符中的一个已经准备好进行I/O时,该函数才返回;返回时告诉进程哪些描述符已经准备好可以进行I/O。
poll调用的流程如下图所示:
最终的poll会调用由驱动实现的对应函数,在函数里面将等待的文件描述符表增加到等待队列上,具体实现如下:
unsigned int buttons_poll (struct file *filp, struct poll_table_struct *tb)
{
unsigned int mask = 0;
poll_wait(filp,&buttons_waitq,tb);
if(ev_press)
mask |= POLLIN | POLLRDNORM;
return mask;
}
用户程序修改如下:
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/select.h>
#include <sys/time.h>
#include <poll.h>
#include <errno.h>
static int cnt=0;
int main(void)
{
int buttons_fd;
unsigned char buttons=0 ;
struct pollfd fds[1];
int ret = 0;
buttons_fd = open("/dev/buttons", 0);
if (buttons_fd < 0) {
perror("open device buttons");
return -1;
}
fds[0].fd = buttons_fd;
fds[0].events = POLLIN ;
while(1){
ret = poll(fds,sizeof(fds)/sizeof(fds[0]),5000);
if(ret == 0)
printf("time out.\n");
else{
read(buttons_fd,&buttons,1);
printf("%dKEY%02x entered.\n",cnt++,buttons);
}
}
close(buttons_fd);
return 0;
}
下载并编译运行截图如下: