linux 阻塞 open 作为对 EBUSY 的替代
当设备不可存取,返回一个错误常常是最合理的方法,但是有些情况用户可能更愿意等待 设备. ? 例如,如果一个数据通讯通道既用于规律地预期地传送报告(使用 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上以root用户身份调用SCHED_FIFO线程的pthread_crea
- linux MySql 在 Master 主从复制配置
- linux – 双主OCFS2 DRBD遇到了裂脑.在这种情况下,恢复总是
- LINUX学习:Too many open files 问题解决方法
- linux – Ubuntu Live CD的默认用户名和密码是什么?
- linux – 故障转移Internet连接?
- ACL访问控制列表——扩展访问控制列表(实操!!!)
- 用于备份的rsync:没有–remove选项和旋转……?
- linux – 修复graid mini磁盘上损坏的GPT分区
- Linux Mono等效的.NET Windows服务