从多个连接向单个文件追加文本的最有效方法是什么

Sim*_*lon 7 parallel-processing foreach file-io r

我已经看到了很多关于写入文件的问题,但我想知道打开文本文件最有效的方法是什么,附加一些数据然后在你要从多个连接写入时再次关闭它(即并行计算情况),并不能保证每个连接何时都要写入文件.

例如,在下面的玩具示例中,它只使用我桌面上的核心,它似乎工作正常,但我想知道如果写入时间越长并且写入文件的进程数量增加,此方法是否容易失败(特别是在可能存在延迟的网络共享中).

任何人都可以建议一种强大的,明确的方式,当可能有其他想要同时写入文件的从属进程时,应该打开,写入然后关闭连接吗?

require(doParallel)
require(doRNG)

ncores <- 7
cl <- makeCluster( ncores , outfile = "" )
registerDoParallel( cl )

res <- foreach( j = 1:100 , .verbose = TRUE , .inorder= FALSE ) %dorng%{
    d <- matrix( rnorm( 1e3 , j ) , nrow = 1 )
    conn <- file( "~/output.txt" , open = "a" )
    write.table( d , conn , append = TRUE , col.names = FALSE )
    close( conn )
}
Run Code Online (Sandbox Code Playgroud)

我正在寻找最好的方法,或者甚至是最好的方法.也许R并foreach自动处理我称之为writelock问题的事情?

谢谢.

Ste*_*ton 6

foreach 包没有提供文件锁定机制来防止多个工作人员同时写入同一个文件。这样做的结果将取决于您的操作系统和文件系统。在使用分布式文件系统(如 NFS)时,我会特别担心结果。

相反,我会更改您打开输出文件的方式以包含工作人员的进程 ID:

conn <- file( sprintf("~/output_%d.txt" , Sys.getpid()) , open = "a" )
Run Code Online (Sandbox Code Playgroud)

如果需要,您可以在 foreach 循环返回后连接文件。

当然,如果您使用多台机器,您可能有两个具有相同进程 ID 的工作进程,因此您也可以在文件名中包含主机名Sys.info()[['nodename']],例如使用 .