使用用户空间中的常规文件模仿 Linux 设备模型
Posted
技术标签:
【中文标题】使用用户空间中的常规文件模仿 Linux 设备模型【英文标题】:Mimicing the Linux device model with regular files in userspace 【发布时间】:2016-01-13 21:15:37 【问题描述】:我想通过带有文件的目录结构来表示守护程序的状态。守护进程负责提供一个外壳接口来控制传感器。类似于 Linux 设备模型或 GPIO 控制台接口的实现方式,只是使用普通文件,在用户空间中用 Python 编写:)。
例子:
守护程序运行并创建列出可用传感器的目录结构。目录结构的外观示例:
sensors
`-- sensor1
`-- sensor-ouput
sensor-ouput
只是一个普通文件,用作当前传感器值的抽象。
这是创建示例结构的代码:
import time,os
if not os.path.exists('sensors/sensor1'):
os.makedirs('sensors/sensor1')
f = open('sensors/sensor1/sensor-ouput','w+')
for i in range(100):
time.sleep(1)
f.seek(0)
f.write(str(i))
f.flush()
f.close()
问题:
为什么我可以在守护进程运行时写入文件?echo 1 > sensor-ouput
不会报错。
只有一个进程写入文件并可能同时读取多个进程。在这些情况下,我是否遗漏了一些同步问题?
鉴于文件是在 ramfs 分区上打开的,这种方法是否落后于使用命名管道?
【问题讨论】:
因为你不能做内核能做的事情。绝对地;内核从不真正写入文件。命名管道是一个完全不同的问题的解决方案。kernel never actually writes files
如果我将它们写入内存,它们也不会出现在这个解决方案中
如果您将文件写入 ramdisk,您仍在写入文件。
IMO 一种更好的方法是像内核那样做,即创建一个虚拟文件系统;使用保险丝很容易做到。当其他应用程序尝试读取(或执行其他操作)您公开的“假文件”时,fuse 会调用您的函数,而不是不断地向文件写入(可能无用的)内容(也会让您自己暴露于竞争条件等)。跨度>
【参考方案1】:
您可以写入文件,因为默认情况下文件未锁定。你需要用 os.lockf() 锁定它。
您的多个读者可能会在您期望相同的地方读取不同的值。考虑以下场景
作家写 10 阅读器 #1 读取 10 阅读器 #2 读取 10 作家写 11 阅读器 #3 读取 11此时阅读器#3 与阅读器#1 和#2 相比处于不同的状态。
命名管道是 FIFO 结构,它们确保消息的顺序,而文件没有。另一方面,管道不是持久的,一旦消息被读取,它就会消失。
编辑:实际上 fcntl.flock() 可能是您想要锁定的,而不是 os.lockf()
【讨论】:
以上是关于使用用户空间中的常规文件模仿 Linux 设备模型的主要内容,如果未能解决你的问题,请参考以下文章