比较并交换 POSIX 兼容的文件系统对象
Compare-and-Swap over POSIX-compliant filesystem objects
POSIX 兼容的操作系统可以对文件系统对象(文件和文件夹)进行原子操作。这是这样的列表 presumably atomic operations:
- 重命名或移动文件或文件夹
- 创建硬链接
- 创建符号链接
- 创建文件夹
- 创建并打开一个空文件
是否可以构建基于这些操作来操作文件的比较和交换算法?
假设我们有几个进程在单个文件上并发执行 read/write。文件以其修订为特征。假设修订被添加到文件名中,并且有一个指向文件的符号链接,进程可以使用它来读取它。这些进程不能(出于某些原因)与互斥量、信号量等同步,但它们能够创建辅助文件和文件夹。他们是否能够对文件执行基于修订的比较和交换修改(创建新文件、创建并重命名符号链接),这意味着如果多个进程要同时修改它,一个会成功,其余的会成功失败并显示一些错误代码?
该算法必须能够防止在算法的任何步骤突然终止任何进程。
天哪。
让我们假设每个进程都可以访问一个唯一的标识符,以避免破坏对称性的问题。这是一次性共识对象的无等待实现。
- 创建一个具有唯一名称的目录。
- 在该目录中创建一个文件,其名称是创建进程的输入。
- 将目录重命名为共识对象的名称。这将失败,除非这是第一次这样的重命名。
- 列出我们尝试重命名的目录。里面的文件名是共识决定的。
现在可以simulate an arbitrary object in a wait-free manner,在分布式计算中使用标准结果。享受垃圾收集的乐趣 =P
如果您在原子操作列表中考虑 fcntl(2),则可以轻松构建通用互斥原语。我使用 flock(1) 命令行工具定期在 shell 脚本中执行此操作。 (flock(1) 是 util-linux-ng 包的一部分。)
flock(2) 未由 POSIX 指定,但 fcntl(2) 指定。我认为 flock(1) 在某些情况下(例如 NFS)可能会使用 fcntl(2)。
所以算法是这样的:
- 对您要操作的资源所独有的某个文件执行非阻塞 fcntl()。这可能是数据文件本身,或者每个进程都同意用作互斥对象的某个空文件。
- 2a。如果fcntl成功,交换文件中的数据。
- 2b。如果 fcntl 不成功,请不要触摸数据文件。
- 释放文件上的 fcntl。
您当然可以执行阻塞 fcntl(2),但是无法知道每个进程阻塞和唤醒的顺序,因此这是否合适取决于应用程序。
请注意,fcntl(2) 是建议性的,因此它不会阻止对数据文件的不必要操作。
POSIX 兼容的操作系统可以对文件系统对象(文件和文件夹)进行原子操作。这是这样的列表 presumably atomic operations:
- 重命名或移动文件或文件夹
- 创建硬链接
- 创建符号链接
- 创建文件夹
- 创建并打开一个空文件
是否可以构建基于这些操作来操作文件的比较和交换算法?
假设我们有几个进程在单个文件上并发执行 read/write。文件以其修订为特征。假设修订被添加到文件名中,并且有一个指向文件的符号链接,进程可以使用它来读取它。这些进程不能(出于某些原因)与互斥量、信号量等同步,但它们能够创建辅助文件和文件夹。他们是否能够对文件执行基于修订的比较和交换修改(创建新文件、创建并重命名符号链接),这意味着如果多个进程要同时修改它,一个会成功,其余的会成功失败并显示一些错误代码?
该算法必须能够防止在算法的任何步骤突然终止任何进程。
天哪。
让我们假设每个进程都可以访问一个唯一的标识符,以避免破坏对称性的问题。这是一次性共识对象的无等待实现。
- 创建一个具有唯一名称的目录。
- 在该目录中创建一个文件,其名称是创建进程的输入。
- 将目录重命名为共识对象的名称。这将失败,除非这是第一次这样的重命名。
- 列出我们尝试重命名的目录。里面的文件名是共识决定的。
现在可以simulate an arbitrary object in a wait-free manner,在分布式计算中使用标准结果。享受垃圾收集的乐趣 =P
如果您在原子操作列表中考虑 fcntl(2),则可以轻松构建通用互斥原语。我使用 flock(1) 命令行工具定期在 shell 脚本中执行此操作。 (flock(1) 是 util-linux-ng 包的一部分。)
flock(2) 未由 POSIX 指定,但 fcntl(2) 指定。我认为 flock(1) 在某些情况下(例如 NFS)可能会使用 fcntl(2)。
所以算法是这样的:
- 对您要操作的资源所独有的某个文件执行非阻塞 fcntl()。这可能是数据文件本身,或者每个进程都同意用作互斥对象的某个空文件。
- 2a。如果fcntl成功,交换文件中的数据。
- 2b。如果 fcntl 不成功,请不要触摸数据文件。
- 释放文件上的 fcntl。
您当然可以执行阻塞 fcntl(2),但是无法知道每个进程阻塞和唤醒的顺序,因此这是否合适取决于应用程序。
请注意,fcntl(2) 是建议性的,因此它不会阻止对数据文件的不必要操作。