当设备不可存取, 返回一个错误常常是最合理的方法, 但是有些情况用户可能更愿意等待 设备.

例如, 如果一个数据通讯通道既用于规律地预期地传送报告(使用 crontab), 也用于根据 用户的需要偶尔地使用, 对于被安排的操作最好是稍微延迟, 而不是只是因为通道当前忙 而失败.

这是程序员在设计一个设备驱动时必须做的一个选择之一, 并且正确的答案依赖正被解决
的实际问题.

对 EBUSY 的替代, 如同你可能已经想到的, 是实现阻塞
open. scullwuid 设备是一个在 打开时等待设备而不是返回 -EBUSY 的 sculluid 版本. 它不同于 sculluid 只在下面的 打开操作部分:

spin_lock(&scull_w_lock); while (!
scull_w_available())

{

spin_unlock(&scull_w_lock);

if (filp->f_flags
& O_NONBLOCK) return -EAGAIN;

if
(wait_event_interruptible (scull_w_wait, scull_w_available())) return
-ERESTARTSYS; /* tell the fs layer to handle it */

spin_lock(&scull_w_lock);

}

if (scull_w_count == 0)

scull_w_owner =
current->uid; /* grab it */ scull_w_count++;

spin_unlock(&scull_w_lock);

这个实现再次基于一个等待队列. 如果设备当前不可用, 试图打开它的进程被放置到等待 队列直到拥有进程关闭设备.

release 方法, 接着, 负责唤醒任何挂起的进程:

static int scull_w_release(struct inode *inode,
struct file *filp)

{

int
temp; spin_lock(&scull_w_lock); scull_w_count--;

temp = scull_w_count; spin_unlock(&scull_w_lock);

if (temp ==
0)

wake_up_interruptible_sync(&scull_w_wait); /*
awake other uid's */ return 0;

}

这是一个例子, 这里调用 wake_up_interruptible_sync 是有意义的. 当我们做这个唤醒, 我们只是要返回到用户空间, 这对于系统是一个自然的调度点. 当我们做这个唤醒时不是 潜在地重新调度, 最好只是调用 "sync" 版本并且完成我们的工作.

阻塞式打开实现的问题是对于交互式用户真的不好, 他们不得不猜想哪里出错了. 交互式 用户常常调用标准命令, 例如 cp 和 tar, 并且不能增加 O_NONBLOCK 到 open 调用. 有

些使用磁带驱动器做备份的人可能喜欢有一个简单的"设备或者资源忙"消息, 来替代被扔 在一边猜为什么今天的硬盘驱动器这么安静, 此时 tar 应当在扫描它.

这类的问题(需要一个不同的, 不兼容的策略对于同一个设备)最好通过为每个存取策略实 现一个设备节点来实现. 这个做法的一个例子可在 linux 磁带驱动中找到, 它提供了多 个设备文件给同一个设备. 例如, 不同的设备文件将使驱动器使用或者不用压缩记录, 或 者自动回绕磁带当设备被关闭时.

linux 阻塞 open 作为对 EBUSY 的替代的更多相关文章

  1. Linux 文件系统错误的修复方法 ddrescue替代dd的恢复软件 备用超级块

    Linux 文件系统错误的修复方法  ddrescue替代dd的恢复软件  备用超级块 最近处理的一件 linux 服务器断电导致文件系统启动后文件系统不可读写,数据不可用的案例,现总结下 Linux ...

  2. Linux下python默认版本切换成替代版本

    本文链接自http://www.myhack58.com/Article/48/66/2016/71806.htm 当你安装 Debian Linux 时,安装过程有可能同时为你提供多个可用的 Pyt ...

  3. 将Linux下python默认版本切换成替代版本

    本文链接自http://www.myhack58.com/Article/48/66/2016/71806.htm 当你安装 Debian Linux 时,安装过程有可能同时为你提供多个可用的 Pyt ...

  4. Linux下新的网络管理工具ip替代ifconfig零压力

    如果你使用 Linux 足够久,那么你自然知道一些工具的来与去.2009年 Debian 开发者邮件列表宣布放弃使用缺乏维护的 net-tools 工具包正是如此.到今天 net-tools 仍然被部 ...

  5. linux进程 阻塞和非阻塞操作

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

  6. Linux 设备驱动 Edition 3

    原文网址:http://oss.org.cn/kernel-book/ldd3/index.html Linux 设备驱动 Edition 3 By Jonathan Corbet, Alessand ...

  7. Linux 驱动开发

    linux驱动开发总结(一) 基础性总结 1, linux驱动一般分为3大类: * 字符设备 * 块设备 * 网络设备 2, 开发环境构建: * 交叉工具链构建 * NFS和tftp服务器安装 3, ...

  8. Windows下与Linux下编写socket程序的区别 《转载》

     原文网址:http://blog.chinaunix.net/uid-2270658-id-308160.html [[Windows]] [Windows: 头文件的区别] #include< ...

  9. inotify-java linux系统监听文件发生变化,实时通知java程序

    1 Overview     最近公司的一个任务需要实时监控文件系统中某个文件的内容变化.由于程序本身由Java编写,因此使用了inotify- java(http://code.google.com ...

随机推荐

  1. 什么是PV UV

    PV是网站分析的一个术语,用以衡量网站用户访问的网页的数量.对于广告主,PV值可预期它可以带来多少广告收入.一般来说,PV与来访者的数量成正比,但是PV并不直接决定页面的真实来访者数量,如同一个来访者 ...

  2. No.3 Verilog 语言要素

    - 标识符 任意字母.数字."$"和"_"组成,标识符第一个不能是数字. - 注释 ()/*可扩展多行*/ ()//本行结束 - 系统函数 以$字符开始的标识符 ...

  3. 每天一个linux命令(1): which命令

    0.学习时间: 2014-05-15 which命令用来在PATH指定的路径中查找特定的文件, 并返回第一个找到的结果. 1. 命令格式:  which 文件名 2.命令功能 一般使用which命令来 ...

  4. 杨柳目-杨柳科-Info-新闻:“北京三害”之一,危害堪比雾霾和沙尘,杨絮为什么会肆虐

    ylbtech-杨柳目-杨柳科-Info-新闻:“北京三害”之一,危害堪比雾霾和沙尘,杨絮为什么会肆虐 1.返回顶部 1. “北京三害”之一,危害堪比雾霾和沙尘,杨絮为什么会肆虐 18-05-0817 ...

  5. sql表连接 —— join

    一.内连接 —— INNER JOIN 内连接是最常见的一种连接,只连接匹配的行. 表1: 表2: 执行查询: select StudentId as 学生编号,StudentName as 姓名,G ...

  6. IDI Open 2016 H 字符串模拟题

    H - Palindrome Names 题意:给定一个字符串,每次可以向末尾添加一个字符或者更改一个字符.求使得字符串为回文串(从前往后和从后往前读一样)所花费的最小步数. 题解: 看来需要多思考啊 ...

  7. Warning!程序员们小心被技术绑架

    通常我们说程序员需要在某个技术方向上积累到一定的厚度,要能够运用技术有效地解决实际问题.可是当程序员在某一项技术上浸淫时间长了之后,却经常会出现另外的问题,那就是:看待问题时受限于自身的技术积累. 我 ...

  8. android service中stub作用是什么?

    AIDL(android 接口描述语言)是一个IDL语言,它可以生成一段代码,可以使在一个android设备上运行的两个进程使用内部通信进程进行交互.如果你需要在一个进程中(例如:在一个Activit ...

  9. linux下修改gcc编译器版本

    可以使用如下命令行来让 gcc 选择不同的 C++ 版本: g++ -std=c++11 main.cpp 在你的系统中,由于编译器或是编译器设定上的差别,操作也许有所不同.    

  10. day3_python之函数参数

    一.形参 在定义函数时,括号内的参数称为形参,特点:形参就是变量名 def foo(x, y): # x=1,y=2 print(x) print(y) 二.实参 在调用函数时,括号内的参数成为实参, ...