1、poll存在于内核空间,对应于用户空间的select。
有很多用系统调用(用户空间)对应到驱动(内核空间)的函数:
系统调用(用户空间) 驱动(内核空间)
Open Open
Close Release
Read Read
Write Write
Ioctl Ioctl
lseek llseek
Select/poll Poll
2、Poll设备方法的作用
① 使用poll_wait将等待队列添加到poll_table中。
②返回描述设备是否可读或可写的掩码 mask。
相关的位掩码如下:
POLLIN设备可读
POLLRDNORM数据可读
POLLOUT设备可写
POLLWRNORM数据可写
设备可读通常返回(POLLIN|POLLRDNORM )
设备可写通常返回(POLLOUT|POLLWRNORM )
3. 等待事件的发生
wait_event(wq,condition)
#define wait_event_interruptible(wq, condition) \
wq : 是要去等的等待队列
condition : a C expression for the event to wait for
如果condition 表达为假 ,wait_event 会进入睡眠 ,等待被唤醒(被wake_up唤醒)
4. 唤醒队列 wake_up(q)
q: 唤醒等待队列 ,等待队列结构体指针
#define wake_up(x) __wake_up(x, TASK_NORMAL, 1, NULL)
5、define DECLARE_WAIT_QUEUE_HEAD(name) \
wait_queue_head_t name = __WAIT_QUEUE_HEAD_INITIALIZER(name)
根据传入的字符串name,创建一个名为name的等待队列头
1. 应用程序中调用select查询指定文件是否可读、可写或异常
2. 系统会调用驱动中的poll函数(file_operations中的),查询指定文件是否可读、可写
3. poll返回文件否可读、可写
4. 如果应用程序调用select时,没有加超时,这时系统会调用wait_event_interruptible,
根据select监控的文件描述符集,来确定都等待队列还是写等待队列上等待,读写任何一个条件成立,
当前进程都会被从等待队列上摘除。
如果应用程序调用select时,有加超时, 这时系统会调用wait_event_interruptible_timeout
5. 如果wait_event_timeout超时,系统会再次调用驱动中的poll函数确认指定文件是否可读、可写或异常状态
如果有别的进程调用wake_up_interruptible(如果是读等待队列,这个函数在驱动write函数中调用,
如果是写等待队列,这个函数在驱动read函数中调用),
系统会再次调用驱动中的poll函数确认指定文件是否可读、可写或异常状态
7. select系统调用返回
poll()函数:这个函数是某些Unix系统提供的用于执行与select()函数同等功能的函数,下面是这个函数的声明:
#include
int poll(struct pollfd fds[], nfds_t nfds, int timeout);
参数说明:
fds:是一个struct pollfd结构类型的数组,用于存放需要检测其状态的Socket描述符;每当调用这个函数之后,系统不会清空这个数组,操作起来比较方便;特别是对于 socket连接比较多的情况下,在一定程度上可以提高处理的效率;这一点与select()函数不同,调用select()函数之后,select() 函数会清空它所检测的socket描述符集合,导致每次调用select()之前都必须把socket描述符重新加入到待检测的集合中;因 此,select()函数适合于只检测一个socket描述符的情况,而poll()函数适合于大量socket描述符的情况;