0

我想在每个线程内执行一个tclTaskSchedule计时器(从包中)。但是,以下最小代码tcltk2doParallel

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

实际上,调用foreachwith.export = "testfn"会导致相同的错误。

那么出了什么问题呢?


我为什么要这样做?最后,我想以固定的时间间隔异步轮询多个数据源,并且每个数据源都有自己特定的轮询间隔)

4

2 回答 2

1

我同意 Roland 的观点,即问题在于tclTaskSchedule评估其论点的方式。我的解决方案并不漂亮,但我通过在 foreach 循环中导出testfnusingclusterExport并分配给工作人员的全局环境来使其工作:i

testfn <- function() print(paste("hello from", i))
clusterExport(cl, "testfn")

foreach(i=1:n, .packages = c("tcltk", "tcltk2"), .verbose = F) %dopar% {
    i <<- i
    tclTaskSchedule(1000, testfn(), id = paste0("task", i), redo = 10)
}

我可能也会传递.noexport="testfn"给 foreach,但这并不是必需的。

于 2013-11-01T00:31:03.487 回答
0

您还将发现另一个问题,即使没有tclTaskSchedule: 并行循环print中的语句也不会输出到交互式会话: foreach

来自博客文章

foreach 的一个问题是它为循环的每次迭代创建新的 RScript 实例,这会阻止状态消息被记录到控制台输出。

一种解决方法是创建一个输出日志文件:

cat("", file="log.txt")
testfn <- function() cat("hello from", i, "\n", file="log.txt", append=TRUE)
foreach(i=1:n, .packages = c("tcltk", "tcltk2"), .verbose = T) %dopar% {
    tclTaskSchedule(1000, testfn(), id = paste0("task", i), redo = 10)
}

然后可以使用tail -f log.txt终端bash对其进行监控。

于 2013-11-01T00:43:12.530 回答