Rap*_*ter 6 filesystems locking r read-write
我将如何阻止对文件的访问,直到涉及该文件的读写过程的特定函数返回?
我经常想创建某种中央注册表,并且可能有多个R进程参与读取和写入该注册表(以"穷人的并行化"设置为例,其中不同的进程彼此独立地运行,除非尊重到注册表访问).
我不喜欢依赖任何DBMS,例如SQLite的,PostgreSQL的,MongoDB的等早在devel的过程.即使我后来可能使用DBMS,基于文件系统的解决方案仍可能是一个方便的后备选项.因此,我很好奇我如何通过基本R功能实现它(充其量).
我知道,与DBMS解决方案相比,在并行设置中对文件系统进行大量读写操作并不是非常有效.
我在MS Windows 8.1(64位)上运行
当两个或多个R进程同时尝试写入或读取文件时,究竟发生了什么?操作系统是否自动找出"访问顺序"并执行"第二次"进程等待或是否会触发错误,因为第一个进程可能会阻止文件访问?我怎么能阻止第二个进程返回错误,而是"等待"直到轮到他?
除了rredis包之外:MS Windows上还有其他共享内存选项吗?
注册表文件的路径:
path_registry <- file.path(tempdir(), "registry.rdata")
Run Code Online (Sandbox Code Playgroud)
注册事件的示例函数:
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
}
Run Code Online (Sandbox Code Playgroud)
注册的示例内容:
x <- new.env()
x$a <- TRUE
x$b <- letters[1:5]
Run Code Online (Sandbox Code Playgroud)
请注意,内容通常是"嵌套的",即RDBMS无论如何都不会真正"有用",或者至少在写入数据库之前会涉及一些规范化步骤.这就是为什么我更喜欢environments(唯一的变量ID和传递引用是可能的)list而且,如果有人使用真正的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)
Run Code Online (Sandbox Code Playgroud)
检查注册表内容:
load(path_registry)
ls(registry)
Run Code Online (Sandbox Code Playgroud)
请参阅filelock R 软件包,自 2018 年起可用。它是跨平台的。我在 Windows 上使用它,没有发现任何问题。
请务必阅读文档。
?filelock::lock
Run Code Online (Sandbox Code Playgroud)
尽管文档建议保留锁定文件,但我在多进程环境中的函数退出时删除它没有任何问题:
on.exit({filelock::unlock(lock); file.remove(path.lock)})
Run Code Online (Sandbox Code Playgroud)