linux poll 原理,Linux Poll机制学习及其应用

最近学习Poll花了一些时间去了解Linux内部的机制,主要是看了下韦东山老师的关于这个Poll总结后,感觉还是有些疑惑,一番纠结后终于有些明朗了。所以写写总结分享下。

一、Poll应用程序接口

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

fds为指向待查询的设备文件数组;

nfds描述第一个参数fds中有多少个设备;

timeout为查询不到我们期望的结果进程睡眠的时间;

返回值:查询到期望状态的设备文件个数

struct pollfd{

int fd;              /* 文件描述符 */ (待查询的设备)

short events;   /* 等待的事件 */(待查询的设备的状态)

short revents;  /* 实际发生了的事件 */

}

总的来说,Poll提供的接口工作机制如下:

应用程序中调用poll查询文件的状态,首先将fds里面的每个设备文件fd取出,调用它们驱动程序的poll函数,查询是否出现我们期望状态,查询完fds里面所有的设备文件得到满足期望状态的设备文件的数量,如果这个数为0,则poll调用将导致进程就进入睡眠状态,睡眠时间由poll函数设定,如果程序在睡眠状态中fds的某个文件出现我们期望状态,那么poll立即返回,否则一直睡眠到睡眠时间结束为止,返回值为0;如果这个数大于0 ,poll返回满足条件的设备数量。

poll相当于open("/dev/xxx",O_RDWR)阻塞打开文件,区别在于当设备文件无数据可读时poll只导致程序休眠固定时间,而open将导致程序一直休眠到有数据为止。

至于更为详细的内核代码分析,抓住如下主线即可明白了,

(应用程序)poll->sys_poll->do_sys_poll->do_poll->do_pollfd->f_op->poll(驱动)这里不再贴

二、驱动程序

驱动程序里与poll相关的地方有两处:

一是构造file_operation结构时,要定义自己的poll函数。

二是在poll函数中通过poll_wait来调用上面说到的__pollwait函数

staticinline void poll_wait(struct file * filp, wait_queue_head_t * wait_address,poll_table *p)

执行到驱动程序的poll_wait函数时,进程并没有休眠,我们的驱动程序里实现的poll函数是不会引起休眠的。

让进程进入休眠,是前面分析的do_sys_poll函数的30行“__timeout = schedule_timeout(__timeout)”。

poll_wait只是把本进程挂入某队列中,该队列由poll内部提供,应用程序调用poll > sys_poll> do_sys_poll > poll_initwait,do_poll > do_pollfd > 我们自己写的poll函数后,再调用schedule_timeout进入休眠。如果我们的驱动程序发现情况就绪,可以把这个队列上挂着的进程唤醒。

这里就有几个疑问:

1.我们自定义的驱动程序在对应的一个描述符中,经过了Poll等待超时返回后是被调用了几次?

2.在驱动中若不调用poll_wait会怎么样?

第一个问题:

可以在定义的驱动poll函数中插入打印语句,看它打印出几条信息。可以发现,在一次超时返回时,打印出了2条,而这两条分别是进入休眠前后被唤醒时调用了驱动poll函数而打印出的。

所以第一个问题,2次。

第二个问题:

不调用poll_wait则不把本进程加入到队列中,则没办法被唤醒,需要靠其它地方的唤醒机制,比如中断。

笔者测试了按键驱动中把自带的驱动poll函数中的poll_wait注释掉后,则按键似乎失去了实时反应,只有在按键按下长时间时才会发现。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值