加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Linux > 正文

linux 阻塞 open 作为对 EBUSY 的替代

发布时间:2020-12-13 23:13:07 所属栏目:Linux 来源:网络整理
导读:当设备不可存取,返回一个错误常常是最合理的方法,但是有些情况用户可能更愿意等待 设备. ? 例如,如果一个数据通讯通道既用于规律地预期地传送报告(使用 crontab),也用于根据 用户的需要偶尔地使用,对于被安排的操作最好是稍微延迟,而不是只是因为通道当前忙

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

?

例如,如果一个数据通讯通道既用于规律地预期地传送报告(使用 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 磁带驱动中找到,它提供了多 个设备文件给同一个设备. 例如,不同的设备文件将使驱动器使用或者不用压缩记录,或 者自动回绕磁带当设备被关闭时.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读