文件数据IO 的细节分析:

参考:
Linux设备驱动开发详解:基于最新的Linux4.0内核:宋宝华编著.

编程离不开数据, 所以数据获取是编程的第一步.

1.文件打开方式

数据IO可以是阻塞式式的或非阻塞式的.  
例如读取数据,当数据没有准备好时,是把读取线程或进程阻塞,还是立即返回一个无数据的错误. 这可由用户选择.
默认的文件打开方式是阻塞式读写. 如果想非阻塞式读写,需要如此打开文件:
int fd = open(path,O_RDONLY | O_NONBLOCK)  
这个path 可能是个设备文件,例如:/dev/globalfifo  
这个open操作将会调用到驱动中的globalfifo_open(struct inode *inode, struct file *filp);
打开的属性(O_RDONLY | O_NONBLOCK) 会保留在filp->f_flags中
filp 是系统提供的一个文件结构指针, 打开操作只需要把你的私有数据挂到filp->private_data
    filp->private_data = globalfifo_devp;
inode 对应一个文件节点,这里没有用到,先不管它.

2.用户的read操作

例如:
read(fd,buf,5);
将会调用到驱动的read 函数
ssize_t globalfifo_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
传来的参数包括那个特定的filp 指针, 从这可以拿到源数据信息.
还有用户空间的地址和大小. 向这个地方copy
最后1个参数ppos, 是位置偏移指针, 从这里(*ppos)=offset 可以拿到地址偏移.
所以当用户读走了count 个数据,为了保证下次继续读新数据,你需要把偏移更正一下.
        *ppos += count;

3.用户的seek操作

seek 函数能够直接改变文件的读写指针, 他是如何使用的?
off_t lseek(int fd, off_t offset, int whence);
对应于驱动的

static loff_t globalfifo_llseek(struct file *filp, loff_t offset, int orig)
这个偏移值offset, 会被保存到filp->pos 处
从开始处偏移 filp->f_pos = (unsigned int)offset; 或者从现在处偏移
filp->f_pos += offset;
这样用户读取时能被正确的传递偏移

4.再谈read 操作

驱动中的读函数,当数据不可读时,如果是O_NONBLOCK 模式,应立即返回

   while (dev->current_len == 0) {if (filp->f_flags & O_NONBLOCK) {ret = -EAGAIN;goto out;}}

否则需要挂起执行的进程,当资源可用时再唤醒.
挂起很简单,调用
        __set_current_state(TASK_INTERRUPTIBLE); //也允许信号唤醒
        schedule();
即可.
如何唤醒?  这需要把当前进程加到一个等待队列中
    DECLARE_WAITQUEUE(wait, current);
    add_wait_queue(&dev->r_wait, &wait);
当有数据写入时,唤醒这个等待队列
    wake_up_interruptible(&dev->r_wait);

5. 支持poll 操作的驱动 (select 模型,及epoll 模型)

我们都知道著名的select 函数
    select(fd + 1, &rfds, &wfds, NULL, NULL);
    它能同时监视读,写描述符集, 有一个有效即被唤醒. 它是如何实现的?
原来select 函数会调用驱动的poll 函数,每一个监控的fd的poll都会调用.

static unsigned int globalfifo_poll(struct file *filp, poll_table * wait)
它传来一个poll_table* wait, 应该有进程的信息.

poll_wait(filp, &dev->r_wait, wait);
    poll_wait(filp, &dev->w_wait, wait);
驱动把这个wait 加入到等待队列中, 以后如果资源可用时,会唤醒这个等待队列,从而
select 能够从阻塞中继续执行.
驱动的poll函数并不会阻塞,它加入等待队列后,返回自己的状态就可以了.
    if (dev->current_len != 0) {
        mask |= POLLIN | POLLRDNORM;
    }

if (dev->current_len != GLOBALFIFO_SIZE) {
        mask |= POLLOUT | POLLWRNORM;
    }
    
    return mask;
    这会置位fdset 的对应bit, 使用户知道哪个fd 置位了.

6. 异步IO 模型

   int fd = open("/dev/globalfifo", O_RDWR, S_IRUSR | S_IWUSR); //打开一个文件signal(SIGIO, signalio_handler);    //注册一个SIGIO 信号处理器fcntl(fd, F_SETOWN, getpid());        // 设置本fd为异步IO, 第一步,设置current pidint oflags = fcntl(fd, F_GETFL);fcntl(fd, F_SETFL, oflags | FASYNC); // 设置为异步标记while (1) {sleep(100);}

当然,要支持异步操作,驱动也要做相应修改. 主要是当数据可读时,从驱动向调用者发SIGIO信号

文件数据IO 的细节分析相关推荐

  1. django之:网页伪静态 JsonResponse form表单携带文件数据 CBV源码分析 模板语法传值 模板语法之过滤器 标签 自定义标签函数 过滤器、inclusion_tag模板的继承导入

    目录标题 一:网页伪静态 1.定义 2.如何实现 二:视图层 1.视图函数返回值问题 2.视图层返回json格式的数据 3.form表单携带文件数据 4.CBV源码分析 1.CBV和FBV: 2.CB ...

  2. 多用户企业文件管理系统源码_固定资产管理系统的细节分析

    固定资产管理系统的细节分析是什么?固定资产管理系统的应用在很多企业中都越来越普遍,固定资产管理系统作为信息化管理系统,能有效延长资产使用寿命.提升资产使用效能.降低资产故障率及残值.降低维护与维修成本 ...

  3. 数据导出为 .SAV文件到SPSS软件进行分析的解决过程

    我们的一个产品是做医疗数据分析统计的,核心功能是通过精细的数据过滤条件及灵活的组合方式,给予用户使用严苛条件检索出病人数据,而数据分析这块,我们是通过 R 语言库,编码实现常用的统计分析功能. 有个客 ...

  4. IO流案例,集合到文件数据排序、复制单级和多级文件夹及复制文件的异常处理

    目录 一.集合到文件数据排序 二.复制单级文件夹 三.复制多级文件夹 四.复制文件的异常处理 基本做法: JDK7版本改进: JDK9版本改进: 一.集合到文件数据排序 需求: 键盘录入5个学生信息( ...

  5. 文件数据云计算学习笔记---Hadoop HDFS和MapReduce 架构浅析

    本文是一篇关于文件数据的帖子 媒介 Hadoop是一个基于Java的分布式麋集数据处理和数据分析的软件框架.Hadoop在很大程度上是受Google在2004年白皮书中论述的MapReduce技术的启 ...

  6. Linux五种IO模型性能分析

    转载:http://blog.csdn.net/jay900323/article/details/18141217     Linux五种IO模型性能分析 目录(?)[-] 概念理解 Linux下的 ...

  7. mysql io 100_MySQL服务器 IO 100%的分析与优化方案

    压力测试过程中,如果因为资源使用瓶颈等问题引发最直接性能问题是业务交易响应时间偏大,TPS逐渐降低等.而问题定位分析通常情况下,最优先排查的是监控服务器资源利用率,例如先用TOP 或者nmon等查看C ...

  8. 《数据驱动安全:数据安全分析、可视化和仪表盘》一3.3 读入数据

    本节书摘来华章计算机<数据驱动安全:数据安全分析.可视化和仪表盘>一书中的第3章 ,第3.1节,[美]杰·雅克布(Jay Jacobs)鲍布·鲁迪斯(Bob Rudis) 著 薛杰 王占一 ...

  9. mysql io_MySQL服务器 IO 100%的分析与优化方案

    前言 压力测试过程中,如果因为资源使用瓶颈等问题引发最直接性能问题是业务交易响应时间偏大,TPS逐渐降低等.而问题定位分析通常情况下,最优先排查的是监控服务器资源利用率,例如先用TOP 或者nmon等 ...

最新文章

  1. 计算机二级C语言程序题常见题型,计算机二级C语言题型和评分标准
  2. eclipse安装反编译插件jd-eclipse
  3. Verilog 中的 function
  4. android状态栏半透明灰色,Android7.0沉浸式状态栏蒙灰问题完美解决
  5. 植物大战僵尸食人花无cd逆向分析
  6. 深入浅出线性判别分析(LDA),从理论到代码实现
  7. SQLAlchemy中filter_by()和filter()的用法不同
  8. Akka相关术语 译《fifteen》
  9. CPU 用户时间 系统时间
  10. dstwo linux 模拟器,dstwo使用gba模拟器V1.30版本下载和使用作弊功能的作弊教程
  11. Anaconda添加清华镜像源
  12. arduino nano + nrf24
  13. 第五人格服务器维修中怎么进,第五人格怎么进不去_进不去游戏原因汇总及解决办法_软吧...
  14. 黑马头条从登陆页到个人中心页
  15. 什么软件测试cpu满载,功耗实测——待机/CPU满载/3DMark_CPUCPU评测-中关村在线
  16. Windows下开启Mysql慢查询详解
  17. 计组 | 算数移位及其移位后的空位添补规则
  18. 当我阳了之后是如何用Python来自动买药的
  19. 历数微软迈向成功的重大历史事件
  20. VMware ESXi安装window10方法

热门文章

  1. 小黑盒匹配系统调服务器,刀塔自走棋完美官方匹配系统
  2. CCS6 自己创建一个新工程
  3. Oracle的日期函数
  4. Vulnhub系列:Raven 1
  5. C语言设置自动关机,可以恶搞朋友(慎用!!!!)
  6. 要设计的PCB焊盘总要比IC焊盘大一些,怎么精确摆放PCB焊盘?
  7. C++实现简单的通讯录系统
  8. 【DeepFace】人脸识别模型之DeepFace框架
  9. linux sqlplus显示乱码,scrt访问linux,sqlplus查询中文显示乱码
  10. 深入理解JVM虚拟机14:JVM性能调优的6大步骤,及关键调优参数详解