使用非阻塞 I/O 的应用程序常常使用 poll, select, 每个允许一个进程来决定它是否可读或者写一个或多个文件而不阻塞. 这些调用也可阻塞进程直到任何一个给定集合的文件描述符可用来读或写. 因此, 它们常常用在必须使用多输入输出流的应用程序, 而不必粘连在它们任何一个上.

支持这些调用都需要来自设备驱动的支持. 这个支持由驱动的 poll 方法调用. 这个方法由下列的原型:

unsigned int (*poll) (struct file *filp, poll_table *wait);

这个驱动方法被调用, 无论何时用户空间程序进行 poll, select, 系统调用, 涉及一个和驱动相关的文件描述符. 这个设备方法负责这 2 步:

  • 1. 在一个或多个可指示查询状态变化的等待队列上调用 poll_wait. 如果没有文件描述符可用作 I/O, 内核使这个进程在等待队列上等待所有的传递给系统调用的文件描述符.
  • 2. 返回一个位掩码, 描述可能不必阻塞就立刻进行的操作.

这 2 个操作常常是直接的, 并且趋向与各个驱动看起来类似. 但是, 它们依赖只能由驱动提供的信息, 因此, 必须由每个驱动单独实现.

poll_table 结构, 给 poll 方法的第 2 个参数, 在内核中用来实现 poll, select调用; 它在 中声明, 这个文件必须被驱动源码包含. 驱动编写者不必要知道所有它内容并且必须作为一个不透明的对象使用它; 它被传递给驱动方法以便驱动可用每个能唤醒进程的等待队列来加载它, 并且可改变 poll 操作状态. 驱动增加一个等待队列到 poll_table 结构通过调用函数 poll_wait:

void poll_wait (struct file *, wait_queue_head_t *, poll_table *);

poll 方法的第 2 个任务是返回位掩码, 它描述哪个操作可马上被实现; 这也是直接的. 例如, 如果设备有数据可用, 一个读可能不必睡眠而完成; poll 方法应当指示这个时间状态. 几个标志(通过 定义)用来指示可能的操作:

POLLIN

如果设备可被不阻塞地读, 这个位必须设置.

POLLRDNORM

这个位必须设置, 如果"正常"数据可用来读. 一个可读的设备返回( POLLIN|POLLRDNORM ).

POLLRDBAND

这个位指示带外数据可用来从设备中读取. 当前只用在 Linux 内核的一个地方( DECnet 代码 )并且通常对设备驱动不可用.

POLLPRI

高优先级数据(带外)可不阻塞地读取. 这个位使 select 报告在文件上遇到一个异常情况, 因为 selct 报告带外数据作为一个异常情况.

POLLHUP

当读这个设备的进程见到文件尾, 驱动必须设置 POLLUP(hang-up). 一个调用 select 的进程被告知设备是可读的, 如同 selcet 功能所规定的.

POLLERR

一个错误情况已在设备上发生. 当调用 poll, 设备被报告位可读可写, 因为读写都返回一个错误码而不阻塞.

POLLOUT

这个位在返回值中设置, 如果设备可被写入而不阻塞.

POLLWRNORM

这个位和 POLLOUT 有相同的含义, 并且有时它确实是相同的数. 一个可写的设备返回( POLLOUT|POLLWRNORM).

POLLWRBAND

如同 POLLRDBAND , 这个位意思是带有零优先级的数据可写入设备. 只有 poll 的数据报实现使用这个位, 因为一个数据报看传送带外数据.

应当重复一下 POLLRDBAND 和 POLLWRBAND 仅仅对关联到 socket 的文件描述符有意义: 通常设备驱动不使用这些标志.

static unsigned int mem_p_poll(struct file *filp, poll_table *wait)
{
struct mem_dev *dev = filp->private_data;
unsigned int mask = ; poll_wait(filp, &dev->my_queue, wait); /* Ъ/ if(dev->wr_flag) // M
mask = POLLIN |POLLRDNORM;
else
mask = POLLOUT | POLLWRNORM; return mask;
}

(十二)Linux内核驱动之poll和select的更多相关文章

  1. OMAP4之DSP核(Tesla)软件开发学习(二)Linux内核驱动支持OMAP4 DSP核

    注:必须是Linux/arm 3.0以上内核才支持RPMSG,在此使用的是.config - Linux/arm 3.0.31 Kernel Configuration.(soure code fro ...

  2. Linux内核驱动开发之KGDB原理介绍及kgdboe方式配置

    接博文<Linux内核驱动开发之KGDB单步调试内核(kgdboc方式)>.上篇博文中,仅简单介绍使用串口的Kgbd的流程(kgdboc方式),本文将重点介绍KGDB调试Linux内核的原 ...

  3. 嵌入式C语言自我修养 02:Linux 内核驱动中的指定初始化

    2.1 什么是指定初始化 在标准 C 中,当我们定义并初始化一个数组时,常用方法如下: ] = {,,,,,,,,}; 按照这种固定的顺序,我们可以依次给 a[0] 和 a[8] 赋值.因为没有对 a ...

  4. linux内核驱动模型

    linux内核驱动模型,以2.6.32内核为例.(一边写一边看的,有点乱.) 1.以内核对象为基础.用kobject表示,相当于其它对象的基类,是构建linux驱动模型的关键.具有相同类型的内核对象构 ...

  5. linux 内核驱动--Platform Device和Platform_driver注册过程

    linux 内核驱动--Platform Device和Platform_driver注册过程 从 Linux 2.6 起引入了一套新的驱动管理和注册机制 :Platform_device 和 Pla ...

  6. Unix/Linux环境C编程新手教程(12) openSUSECCPP以及Linux内核驱动开发环境搭建

    1. openSUSE是一款优秀的linux. watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaXRjYXN0Y3Bw/font/5a6L5L2T/font ...

  7. Unix/Linux环境C编程入门教程(12) openSUSECCPP以及Linux内核驱动开发环境搭建

    1. openSUSE是一款优秀的linux. 2.选择默认虚拟机 3.选择稍后安装操作系统 4.选择linux  opensuse 5. 选择默认虚拟机名称 6.设置处理器为双核. 7.内存设置为2 ...

  8. 【引用】Linux 内核驱动--多点触摸接口

    本文转载自James<Linux 内核驱动--多点触摸接口>   译自:linux-2.6.31.14\Documentation\input\multi-touch-protocol.t ...

  9. linux内核驱动学习指南

    1. 参考链接 小白的博客 ONE_Tech 你为什么看不懂Linux内核驱动源码? 求教怎么学习linux内核驱动

随机推荐

  1. 定时爬虫抓当日免费应用:Scrapy + Tkinter + LaunchControl

    花了个周末学了下Scrapy,正好一直想买mindnode,于是顺手做了个爬虫,抓取爱范儿每天的限免应用信息. Thinking 大概思路就是使用LaunchControl每天定时(比如早上9点50, ...

  2. 测试理论--branch testing and boundary testing

    1 branch testing 分支测试 测试代码的所有分支 2 boundary testing 测试 程序的限制条件

  3. HDU 4757 Tree(可持久化字典树)(2013 ACM/ICPC Asia Regional Nanjing Online)

    Problem Description   Zero and One are good friends who always have fun with each other. This time, ...

  4. NO1——线段树

    /* 数组存储 */ /* 预处理 */ #include <iostream> #include <cstdio> #include <algorithm> #i ...

  5. JavaSE复习(二)集合

    Collection List(存取有序,有索引,可以重复) ArrayList 底层是数组实现的,线程不安全,查找和修改快,增和删比较慢 LinkedList 底层是链表实现的,线程不安全,增和删比 ...

  6. [译]在Python中如何使用额enumerate 和 zip 来迭代两个列表和它们的index?

    enumerate - 迭代一个列表的index和item <Python Cookbook>(Recipe 4.4)描述了如何使用enumerate迭代item和index. 例子如下: ...

  7. exec族

    在之前我们已经知道用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数以执行另一个程序.当进程调用一种exec函数时,该进程的用户空间代码和 ...

  8. reactor工作模型

  9. struts2的验证

    1.原理 当浏览器向服务器提交表单数据时,在服务器端需要对表单数据的有效性进行校验. “校验方法”会在“业务方法”之前调用. 2.实现验证的两种方式 struts2校验的两种实现方法: 1. 手工编写 ...

  10. log4net将日志写入ElasticSearch

    log4net将日志写入ElasticSearch https://www.cnblogs.com/huangxincheng/p/9120028.html 很多小步快跑的公司,开发人员多则3-4个, ...