R foreach %dopar% Results



我正在尝试使用foreach%dopar%运行一个函数,该函数将在每次迭代中将其结果传递回自身。 下面的小例子:

require(doParallel)
test_function <- function(data)
{
result <- rbind(data, data)
return(result)
}
test_data <- mtcars
cl                          <-          makeCluster(4)
registerDoParallel(cl)
results                     <-          foreach(i = 1:10) %dopar%
{
aa <- test_function(test_data)
aa$iteration <- i
test_data <- aa
return(aa)
}
stopCluster(cl)

我希望在results中看到的是十个数据框的列表,每个数据框的行数依次翻倍。

似乎在foreach函数中重新定义test_data并不能做到这一点,就像我只是在标准 for 循环中运行这些命令一样 - 如下所示:

results <- list()
for(i in 1:10)
{
aa <- test_function(test_data)
aa$iteration <- i
test_data <- aa
results[[i]] <- aa
}

希望对我在这里忽略的内容有任何见解。

如果我正确理解您的问题,那么您的问题是由于您无法从并行的 for 循环中更新全局变量test_data引起的。

要了解为什么阻止您这样做,请考虑并行化 for 循环中实际发生的情况:在不同线程上运行的多个工作线程并行执行操作,每个工作线程都有自己单独的本地范围的变量。如果他们可以访问任何全局变量(或共享内存),而没有任何控制其访问的保护,那么就有可能损坏变量中存储的任何内容 - 并且这种损坏可能发生的几种不同方式。

防止这种情况是并发控制结构(如信号量)存在的理由。这些允许用户执行您正在尝试的操作,但需要小心才能正确使用。

但是,它们在 R 中不可用。因此,R 应该保护该全局变量test_data不以非线程安全的方式被修改是有意义的。它实际上是在试图保护您的数据。

解决方案是重写代码以删除任何更新全局变量的尝试(如果您仍然想执行任何类型的并行处理)或切换到使用传统的顺序 for 循环(正如一些评论者已经建议的那样)。

最新更新