POLL机制

poll机制:管理多个描述符也是进行轮询,根据描述符的状态进行处理。

poll调用(应用层)

一、应用层:

函数原型:int poll(struct pollfd *fd,nfds_t nfds,int timeout);

函数功能:监视并等待多个文件描述符的属性变化

参数解释:

1、fds:指向一个结构体数组的第0个元素的指针,每个数组元素都是一个struct pollfd结构,用于指定测试某个给定的fd的条件

2、nfds:表示fds结构体数组的长度

3、timeout:表示poll函数的超时时间,单位是毫秒

函数返回值:

1、返回值小于0,表示出错

2、返回值等于0,表示poll函数等待超时

3、返回值大于0,表示poll由于监听的文件描述符就绪返回,并且返回结果就是就绪的文件描述符的个数。

pollfd结构体:

struct pollfd

{

         int fd;

short events;

short revents;

}

(1)fd:每一个pollfd结构体指定了一个被监视的文件描述符,可以传递多个结构体,指示poll()监视多个文件描述符

(2)events:表示告诉操作系统需要监测fd的时间(输入、输出、错误),每一个时间有多个取值。

(3)revents:revents域是文件描述符的操作结果事件,内核在调用返回时设置这个域。events域中请求的任何事件都可能在revents域中返回。

events&revents的取值如下:

 

 

events

revents

事件

描述

可作为输入

可作为输出

POLLIN

数据可读(包括普通数据&优先数据)

POLLOUT

数据可写(普通数据&优先数据)

POLLRDNORM

普通数据可读

POLLRDBAND

优先级带数据可读(linux不支持)

POLLPRI

高优先级数据可读,比如TCP带外数据

POLLWRNORM

普通数据可写

POLLWRBAND

优先级带数据可写

POLLRDHUP

TCP连接被对端关闭,或者关闭了写操作,由GNU引入

POPPHUP

挂起

POLLERR

错误

POLLNVAL

文件描述符没有打开

注意:每个结构体的 events 域是由用户来设置,告诉内核我们关注的是什么,而 revents 域是返回时内核设置的,以说明对该描述符发生了什么事件

二、内核实现:

1. poll > sys_poll > do_sys_poll >poll_initwait,poll_initwait函数注册一下回调函数__pollwait,它就是我们的驱动程序执行poll_wait时,真正被调用的函数。

2. 接下来执行file->f_op->poll,即我们驱动程序里自己实现的poll函数

   它会调用poll_wait把自己挂入某个队列,这个队列也是我们的驱动自己定义的;

   它还判断一下设备是否就绪。

3. 如果设备未就绪,do_sys_poll里会让进程休眠一定时间

4. 进程被唤醒的条件有2:一是上面说的“一定时间”到了,二是被驱动程序唤醒。驱动程序发现条件就绪时,就把“某个队列”上挂着的进程唤醒,这个队列,就是前面通过poll_wait把本进程挂过去的队列。

5. 如果驱动程序没有去唤醒进程,那么chedule_timeout(__timeou)超时后,会重复2、3动作,直到应用程序的poll调用传入的时间到达。

 

posted @ 2020-04-15 16:25  奋斗的蜗牛冲冲  阅读(772)  评论(0编辑  收藏  举报