在我们看全功能的 read 和 write 方法的实现之前, 我们触及的最后一点是决定何时使 进程睡眠. 有时实现正确的 unix 语义要求一个操作不阻塞, 即便它不能完全地进行下去.

有时还有调用进程通知你他不想阻塞, 不管它的 I/O 是否继续. 明确的非阻塞 I/O 由 filp->f_flags 中的 O_NONBLOCK 标志来指示. 这个标志定义于 <linux/fcntl.h>, 被

<linux/fs.h>自动包含. 这个标志得名自"打开-非阻塞", 因为它可在打开时指定(并且起

初只能在那里指定). 如果你浏览源码, 你会发现一些对一个 O_NDELAY 标志的引用; 这 是一个替代 O_NONBLOCK 的名子, 为兼容 System V 代码而被接受的. 这个标志缺省地被 清除, 因为一个等待数据的进程的正常行为仅仅是睡眠. 在一个阻塞操作的情况下, 这是 缺省地, 下列的行为应当实现来符合标准语法:

  • · 如果一个进程调用 read 但是没有数据可用(尚未), 这个进程必须阻塞. 这个进程 在有数据达到时被立刻唤醒, 并且那个数据被返回给调用者, 即便小于在给方法的 count 参数中请求的数量.
  • · 如果一个进程调用 write 并且在缓冲中没有空间, 这个进程必须阻塞, 并且它必 须在一个与用作 read 的不同的等待队列中. 当一些数据被写入硬件设备, 并且在

输出缓冲中的空间变空闲, 这个进程被唤醒并且写调用成功, 尽管数据可能只被部 分写入如果在缓冲只没有空间给被请求的 count 字节.

这 2 句都假定有输入和输出缓冲; 实际上, 几乎每个设备驱动都有. 要求有输入缓冲是 为了避免丢失到达的数据, 当无人在读时. 相反, 数据在写时不能丢失, 因为如果系统调

用不能接收数据字节, 它们保留在用户空间缓冲. 即便如此,
输出缓冲几乎一直有用, 对 于从硬件挤出更多的性能.

在驱动中实现输出缓冲所获得的性能来自减少了上下文切换和用户级/内核级切换的次数. 没有一个输出缓冲(假定一个慢速设备), 每次系统调用接收这样一个或几个字符, 并且当 一个进程在 write 中睡眠, 另一个进程运行(那是一次上下文切换). 当第一个进程被唤 醒, 它恢复(另一次上下文切换), 写返回(内核/用户转换), 并且这个进程重新发出系统 调用来写入更多的数据(用户/内核转换); 这个调用阻塞并且循环继续.
增加一个输出缓 冲可允许驱动在每个写调用中接收大的数据块, 性能上有相应的提高. 如果这个缓冲足够 大, 写调用在第一次尝试就成功 -- 被缓冲的数据之后将被推到设备 -- 不必控制需要返 回用户空间来第二次或者第三次写调用. 选择一个合适的值给输出缓冲显然是设备特定的.

我们不使用一个输入缓冲在 scull 中, 因为数据当发出 read 时已经可用.
类似的, 不用 输出缓冲, 因为数据被简单地拷贝到和设备关联的内存区. 本质上, 这个设备是一个缓冲, 因此额外缓冲的实现可能是多余的. 我们将在第 10 章见到缓冲的使用.

如果指定
O_NONBLOCK, read 和 write 的行为是不同的. 在这个情况下, 这个调用简单 地返回 -EAGAIN(("try it
agin")如果一个进程当没有数据可用时调用 read , 或者如果 当缓冲中没有空间时它调用 write .

如你可能期望的,
非阻塞操作立刻返回, 允许这个应用程序轮询数据. 应用程序当使用 stdio 函数处理非阻塞文件中, 必须小心, 因为它们容易搞错一个的非阻塞返回为 EOF.
它们始终必须检查 errno.

自然地, O_NONBLOCK 也在 open 方法中有意义. 这个发生在当这个调用真正阻塞长时间 时; 例如, 当打开(为读存取)一个 没有写者的(尚无)FIFO, 或者存取一个磁盘文件使用
一个悬挂锁. 常常地, 打开一个设备或者成功或者失败, 没有必要等待外部的事件. 有时, 但是, 打开这个设备需要一个长的初始化, 并且你可能选择在你的 open 方法中支持 O_NONBLOCK , 通过立刻返回 -EAGAIN,如果这个标志被设置. 在开始这个设备的初始化进 程之后. 这个驱动可能还实现一个阻塞 open 来支持存取策略, 通过类似于文件锁的方式. 我们将见到这样一个实现在"阻塞 open 作为对
EBUSY 的替代"一节, 在本章后面.

一些驱动可能还实现特别的语义给 O_NONBLOCK;
例如, 一个磁带设备的 open 常常阻塞 直到插入一个磁带. 如果这个磁带驱动器使用 O_NONBLOCK 打开, 这个 open 立刻成功, 不管是否介质在或不在.

只有 read, write, 和
open 文件操作受到非阻塞标志影响.

linux进程 阻塞和非阻塞操作的更多相关文章

  1. 简述linux同步与异步、阻塞与非阻塞概念以及五种IO模型

    1.概念剖析 相信很多从事linux后台开发工作的都接触过同步&异步.阻塞&非阻塞这样的概念,也相信都曾经产生过误解,比如认为同步就是阻塞.异步就是非阻塞,下面我们先剖析下这几个概念分 ...

  2. Linux设备驱动中的阻塞和非阻塞I/O

    [基本概念] 1.阻塞 阻塞操作是指在执行设备操作时,托不能获得资源,则挂起进程直到满足操作所需的条件后再进行操作.被挂起的进程进入休眠状态(不占用cpu资源),从调度器的运行队列转移到等待队列,直到 ...

  3. 蜕变成蝶~Linux设备驱动中的阻塞和非阻塞I/O

    今天意外收到一个消息,真是惊呆我了,博客轩给我发了信息,说是俺的博客文章有特色可以出本书,,这简直让我受宠若惊,俺只是个大三的技术宅,写的博客也是自己所学的一些见解和在网上看到我一些博文以及帖子里综合 ...

  4. linux驱动编写之阻塞与非阻塞

    一.概念 应用程序使用API接口,如open.read等来最终操作驱动,有两种结果--成功和失败.成功,很好处理,直接返回想要的结果:但是,失败,是继续等待,还是返回失败类型呢?  如果继续等待,将进 ...

  5. python全栈开发day31-操作系统介绍,异步、同步、阻塞、非阻塞,进程

    一.网络编程内容回顾 1.arp协议 #交换机 #广播.单播 2.ip协议 3.tcp和udp协议 tcp:可靠的,面向连接的,字节流传输,长连接 三次握手:一方发送请求,另一方确认请求同时发送请求, ...

  6. Linux设备驱动中的IO模型---阻塞和非阻塞IO【转】

    在前面学习网络编程时,曾经学过I/O模型 Linux 系统应用编程——网络编程(I/O模型),下面学习一下I/O模型在设备驱动中的应用. 回顾一下在Unix/Linux下共有五种I/O模型,分别是: ...

  7. 《linux设备驱动开发详解》笔记——8阻塞与非阻塞IO

    8.1 阻塞与非阻塞IO 8.1.0 概述 阻塞:访问设备时,若不能获取资源,则进程挂起,进入睡眠状态:也就是进入等待队列 非阻塞:不能获取资源时,不睡眠,要么退出.要么一直查询:直接退出且无资源时, ...

  8. Linux中同步与异步、阻塞与非阻塞概念以及五种IO模型

    1.概念剖析 相信很多从事linux后台开发工作的都接触过同步&异步.阻塞&非阻塞这样的概念,也相信都曾经产生过误解,比如认为同步就是阻塞.异步就是非阻塞,下面我们先剖析下这几个概念分 ...

  9. 从linux源码看socket的阻塞和非阻塞

    从linux源码看socket的阻塞和非阻塞 笔者一直觉得如果能知道从应用到框架再到操作系统的每一处代码,是一件Exciting的事情. 大部分高性能网络框架采用的是非阻塞模式.笔者这次就从linux ...

  10. Linux设备驱动中的阻塞和非阻塞I/O <转载>

    Green 博客园 首页 新随笔 联系 订阅 管理 Linux设备驱动中的阻塞和非阻塞I/O   [基本概念] 1.阻塞 阻塞操作是指在执行设备操作时,托不能获得资源,则挂起进程直到满足操作所需的条件 ...

随机推荐

  1. NOIP2016提高A组模拟9.28总结

    这次三道题都是可以AC的. 每道题思路都正确,但每道题都有细节没有注意. 第一题 1.没注意系数为1时可以省略系数: 2.没注意在第一项处理常数后,不能输出+号. 导致丢失20分:一定要多出特殊数据, ...

  2. 威胁快报|首爆,新披露Jenkins RCE漏洞成ImposterMiner挖矿木马新“跳板”

    简介 阿里云安全于近日捕获到一起使用Jenkins RCE漏洞进行攻击的挖矿事件.除挖矿外,攻击者还曾植入具有C&C功能的tsunami木马,也预留了反弹shell的功能,给用户带来极大安全隐 ...

  3. C# 获取上传文件的文件名和后缀名

    //获得要上传的文件 HttpPostedFile file = Request.Files[]; //获得到文件名 string fileName = System.IO.Path.GetFileN ...

  4. Notepad++中Python脚本运行出现语法错误:IndentationError: unindent does not match any outer indentation level

    使用Notepad++编辑python代码运行遇到了这个问题: IndentationError: unindent does not match any outer indentation leve ...

  5. linux包之包管理rpm-yum

    背景 YUM(Yellow dog Updater, Modified)为多个Linux发行版的前端软件包管理器,例如 Redhat RHEL, CentOS & Fedora. YUM通过调 ...

  6. 关于inflate的第3个参数

    关于inf 方法 inflate(int resource, ViewGroup root, boolean attachToRoot) 中,前连个参数都好理解,我比较费解的是第3个参数. 文档中的解 ...

  7. 【NS2】添加mUDP、mUdpSink和mTcpSink模块

    根据柯老师的教材可知,mUDP是UDP的延伸,除了具有UDP的功能外,还能记录所发送的包的信息.mUdpSink可以把接收到的包的信息记录 到文件中.mTcpSink是TCPsink的延伸,除了具有T ...

  8. [软考]之软件过程模型I 标签: 总结软考 2015-10-24 11:58 863人阅读 评论(35) 收藏

    做软考题的时候经常碰到软件工程的题,因为这些题有的很相近,容易混淆,所以在这里总结归纳一下. 软件过程模型: 瀑布模型: 瀑布模型是将软件生存周期中的各个活动规定为依线性顺序连接的若干阶段的模型,包括 ...

  9. python 清空文件夹

    #!/usr/bin/env python# -*- coding:utf-8 -*-import os def del_file(path): for i in os.listdir(path): ...

  10. python 检测文件夹的数据变动

    from watchdog.observers import Observerfrom watchdog.events import *import time class FileEventHandl ...