如何使用future.apply包修改全局变量?附lapply对比示例
问题原因
用plan(multisession)时,future_lapply会启动多个独立的R工作进程,每个进程都有自己的独立内存空间。你定义的cnt只存在主进程里,子进程中的cnt是它的副本,子进程用<<-修改的只是自己内存里的副本,主进程的cnt完全不受影响,所以最后输出还是NULL。
解决方案:用跨进程共享的变量
要让子进程修改主进程能访问的变量,必须用跨进程共享的存储机制,下面是两种可行方法:
方法1:用future::shared()创建共享变量
future包的shared()函数可以创建跨进程共享的变量,子进程对它的修改会同步到主进程:
library(future.apply) plan(multisession) # 创建共享的cnt变量,初始值为NULL cnt <- shared(NULL) f <- function(i) { # 修改共享变量需用`$`访问 cnt$value <- i } fla <- future_lapply(1:5, f) # 查看结果 cnt$value
运行后输出:
[1] 5
方法2:用bigmemory包创建共享向量
如果需要更灵活的数值型共享存储,可以用bigmemory包,它支持跨进程访问同一内存区域:
library(future.apply) library(bigmemory) plan(multisession) # 创建共享的单元素向量,用NA代替NULL初始化 cnt <- big.matrix(nrow = 1, ncol = 1, init = NA, shared = TRUE) f <- function(i) { # 修改共享矩阵的元素 cnt[1,1] <- i } fla <- future_lapply(1:5, f) # 查看结果 cnt[1,1]
运行后输出:
[1] 5
注意事项
- 共享变量的修改是并发的,如果需要保证修改顺序(比如保留最后执行的i值),可能需要用
filelock包加锁避免竞争。 - 如果只是要跟踪进程执行进度,用
progressr包更可靠,它和future生态兼容,专门处理进度跟踪。
内容的提问来源于stack exchange,提问作者mr.T
相关产品推荐
相关产品推荐

