r - R 中的文件锁

标签 r filesystems locking read-write

简短版本

在涉及对该文件的读写过程的特定函数返回之前,我将如何阻止对文件的访问?

<小时/>

用例

我经常想创建某种中央注册表,并且可能有多个 R 进程参与对该注册表的读取和写入(这是一种“穷人的并行化”设置,其中不同的进程彼此独立运行)注册表访问除外)。

不想依赖任何 DBMS,例如 SQLite , PostgreSQL , MongoDB等等在开发过程的早期。即使我以后可能会使用 DBMS,基于文件系统的解决方案仍然可能是一个方便的后备选项。因此,我很好奇如何使用基本 R 功能(最多)来实现它。

我知道,与 DBMS 解决方案相比,在并行设置中对文件系统进行大量读取和写入效率不高。

我在 MS Windows 8.1(64 位)上运行

我想更深入地了解什么

当两个或多个 R 进程尝试同时写入或读取文件时,究竟会发生什么?操作系统是否会自动确定“访问顺序”,并且“第二个”进程是否会等待,或者是否会触发错误,因为文件访问可能会被第一个进程阻止?我怎样才能防止第二个进程返回错误,而是“等待”直到轮到他?

进程的共享工作区

除了rredis软件包:MS Windows 上还有其他共享内存选项吗?

插图

注册表文件的路径:

path_registry <- file.path(tempdir(), "registry.rdata")

注册事件的示例函数:

registerEvent <- function(
    id=gsub("-| |:", "", Sys.time()), 
    values, 
    path_registry
) {
    if (!file.exists(path_registry)) {
        registry <- new.env()
        save(registry, file=path_registry)
    } else {
        load(path_registry)
    }

    message("Simulated additional runtime between reading and writing (5 seconds)")
    Sys.sleep(5)

    if (!exists(id, envir=registry, inherits=FALSE)) {
        assign(id, values, registry)
        save(registry, file=path_registry)
        message(sprintf("Registering with ID %s", id))
        out <- TRUE
    } else {
        message(sprintf("ID %s already registered", id))
        out <- FALSE
    }
    out
}

注册的示例内容:

x <- new.env()
x$a <- TRUE
x$b <- letters[1:5]

请注意,内容通常是“嵌套的”,即 RDBMS 无论如何都不会真正“有用”,或者至少在写入数据库之前会涉及一些规范化步骤。这就是为什么我更喜欢环境(可以使用唯一的变量ID和传递引用)而不是列表,并且如果确实迈出了使用真正的DBMS的一步,我宁愿转向 NoSQL 方法,例如 MongoDB .

注册周期:

实际调用可能分布在不同的进程中,因此存在并发访问尝试的可能性。

我想让其他进程/调用“等待”,直到 registerEvent 读写周期完成,然后再进行读写周期(不会触发错误)。

registerEvent(values=list(x_1=x, x_2=x), path_registry=path_registry)
registerEvent(values=list(x_1=x, x_2=x), path_registry=path_registry)
registerEvent(id="abcd", values=list(x_1=x, x_2=x), 
    path_registry=path_registry)
registerEvent(id="abcd", values=list(x_1=x, x_2=x), 
    path_registry=path_registry)

检查注册表内容:

load(path_registry)
ls(registry)

最佳答案

参见filelock R 包,自 2018 年起提供。它是跨平台的。我在 Windows 上使用它,没有发现任何问题。

请务必阅读文档。

?filelock::lock

尽管文档建议保留锁定文件,但我在多进程环境中的函数退出时删除它没有任何问题:

on.exit({filelock::unlock(lock); file.remove(path.lock)})

关于r - R 中的文件锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23607658/

相关文章:

c++ - 在 C++ 中使用 pthreads 时什么时候需要实现锁定?

r - R中带曲线的直方图

r - block 茎的循环或功能

r - 看似 protected 配对列表的垃圾收集

c - 多进程与多线程共享的文件系统

perl - perl 中的 Unicode,mkdir 练习

android - 如何锁定用户界面?

在 R 中逐行删除重复值

c - 检查文件是否存在于 C 中的最佳方法是什么?

Java并发-离开方法后重置条件