linux驱动---file_operations之poll
简述:
file_operations的poll是驱动提供给应用程序探测设备文件是否有数据可读接口。
应用程序探测文件的接口:
select,poll,epoll三个接口都是应用程序探测设备文件是否有数据可读的接口,没有数据进程阻塞,有数据时唤醒。select和poll差不多,epoll是select、poll的增强版,性能上会更好。
select头文件:
#include <sys/select.h>
poll头文件:
#include <sys/poll.h>
epoll头文件:
#include <sys/epoll.h>
如是ubuntu系统,select.h、poll.h、epoll.h都可以在/usr/include/sys/目录下查看。
三个函数详细说明用法,参考如下博客:
Linux IO模式及 select、poll、epoll详解
linux poll函数
Linux内核中select, poll和epoll的区别
驱动层实现file_operations的poll:
先直接看一个例子:
static DECLARE_WAIT_QUEUE_HEAD(my_waitq); //休眠要挂的等待队列
static unsigned drv_poll(struct file *file, poll_table *wait)
{
unsigned int mask = 0;
poll_wait(file, &my_waitq, wait); // 不会立即休眠
if (有数据)//判断是否有数据
mask |= POLLIN | POLLRDNORM;
return mask;
}
poll_wait:看得出,我们只是提供了一个waitqueue,没有数据时进程会阻塞在这个waitqueue上。驱动poll里面基本上都要用这个函数,定义在头文件:
#include <linux/poll.h>
例子中,进程不会在drv_poll里面阻塞,当mask为0返回时,进程阻塞,什么时候唤醒,需要驱动根据情况去wake up我们定义的waitqueue(my_waitq)。如有数据时,需要告诉系统数据情况,如例子中的mask |= POLLIN | POLLRDNORM,mask不为0不阻塞,根据mask值做出操作。
POLLIN、POLLRDNORM宏定义在include/uapi/asm-generic/poll.h中,说明如下:
POLLIN: 有数据可读。
POLLRDNORM: 有普通数据可读。
POLLRDBAND:有优先数据可读。
POLLPRI:有紧迫数据可读。
POLLOUT:写数据不会导致阻塞。表示有空间可写。
POLLWRNORM:写普通数据不会导致阻塞。表示有空间可写。
POLLWRBAND:写优先数据不会导致阻塞。表示有空间可写。
POLLMSG:SIGPOLL 消息可用。
POLLER:指定的文件描述符发生错误。
POLLHUP:指定的文件描述符挂起事件。
POLLNVAL:指定的文件描述符非法。
总结:驱动接口poll不会阻塞进程,只是返回后,系统会根据返回值是否阻塞进程,如阻塞,需求驱动去唤醒(有数据时wake up)。
poll代码跟踪分析,参考如下博客:
linux的poll机制
更多推荐
所有评论(0)