我想在每个doParallel
线程中执行tclTaskSchedule
计时器(来自tcltk2
包)。但是,下面的最小代码doParallel foreach作用域问题:eval(expr,envir,enclos)中的错误:找不到函数
library(doParallel)
n <- detectCores()
cl <- makeCluster(n, outfile="out.log")
registerDoParallel(cl)
testfn <- function() print(paste("hello from", i))
foreach(i=1:n, .packages = c("tcltk", "tcltk2"), .verbose = T) %dopar% {
tclTaskSchedule(1000, testfn(), id = paste0("task", i), redo = 10)
}
stopCluster(cl)
导致的误差(在控制台印刷不,但在out.log
)
Error in eval(expr, envir, enclos) : could not find function "testfn"
然而,从.verbose = T
说法,我可以从控制台看到即testfn
是获取导出:
automatically exporting the following variables from the local environment:
testfn
事实上,拨打foreach
与.export = "testfn"
会导致相同的错误。
那又怎么了?
(为什么我要这么做?最后,我想poll在固定的时间间隔多个数据源的异步,并且每个数据源都有自己特定的轮询间隔)
我认为这个问题并不是'dopar',而是'tclTaskSchedule',它在环境中做了一些内在的魔法。如果你在'foreach'循环中只放入'print(testfn)',你会发现这个函数是在worker上定义的。但是,不知何故'tclTaskSchedule'在错误的环境中寻找它。我尝试了一些东西,但找不到解决这个问题的方法。 PS:如果你没有并行化运行循环,你会发现你也有懒惰评估的问题。 – Roland
尝试加载'tcltk'。 – Roland