读书笔记:LLD3(2)非堵塞型I/O

非堵塞型I/O:当数据不可用时,进程调用read或write系统调用时,进程不会堵塞,会立即返回,即使现在没有数据可读或者可写。

非堵塞型I/O分为 两种:显示和隐式的。

显示:即将filp->f_flags中的O_NONBLOCK置位。

隐式:在调用read或write系统调用之前,先调用poll select或者epoll 查询该文件是否有数据可读写。

注释:O_NONBLOCK只对read write 和open有效。

           poll select和epoll在调用过程中会堵塞。

poll 和 select(轮询):

用来查询某个或者多个文件描述符上的读取或写入是否会被堵塞。如果现在没有可以读写的文件描述符,则堵塞等待直到有可读写的文件描述符。如果有,则直接返回可以读写的文件描述符。

poll的实现(<linux/poll.h>):

方法原型:unsigned int (*poll) (struct file   *filp, poll_table *wait);

该函数分为两步执行:

在一个或多个可指示poll状态变化的等待队列上调用poll_wait。如果当前没有文件描述符可用来执行I/O,则内核将使进程在传递到该系统调用的所有文件描述符对应的等待队列上等待。

返回一个用来描述操作是否可以立即执行的位掩码。

poll_wait:

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

位掩码:

POLLIN:如果设备可以无堵塞地读取,就设置该位

POLLRDNORM:如果“通常”的数据已经就绪,可以读取,就设置该位。一个可读设备返回(POLLIN | POLLRDNORM)

POLLOUT:如果设备可以无堵塞地写入,就设置该位

POLLWRNORM:如果“通常”的数据已经就绪,可以写入,就设置该位。一个可读设备返回(POLLOUT | POLLWRNORM)

实例代码(lld3  scull/pipe.c):

down(&dev->sem);

poll_wait(filp, &dev->inq,  wait);

poll_wait(filp, &dev->outq,wait);

if (dev->rp != dev->wp)

            mask | = POLLIN | POLLRDNORM;

if (spacefree(dev))

             mask | = POLLOUT | POLLWRNORM;

up(&dev->sem);

return mask;


2016.04.14

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 名称 libev - 一个 C 编写的功能全面的高性能事件循环。 概要 示例程序 关于 libev Libev 是...
    hanpfei阅读 15,416评论 0 5
  • 看到网上有不少讨论epoll,但大多不够详细准确,以前面试有被问到这个问题。不去更深入的了解,只能停留在知其然...
    电台_Fang阅读 11,958评论 0 8
  • make menuconfig过程解析作者 codercjg 在 28 九月 2015, 5:27 下午 make...
    codercjg阅读 1,003评论 0 1
  • 一、概述 I/O复用使得程序能同时监听多个文件描述符,这对提高程序的性能至关重要。 I/O复用虽然能同时监听多个文...
    saviochen阅读 1,099评论 0 4
  • 小小的孩子 流着长长的鼻涕 春天里的小河边 小孩子呀 沾着泥巴的手里 是死去的蝌蚪 夏天里的小河边 一张一张的网 ...
    马一月阅读 175评论 0 0