我想将rJava
与mcparallel
结合使用,但显然the JVM cannot be forked。因此,需要为每个子进程启动单独的JVM实例,例如:
library(rJava)
library(parallel)
myfile <- system.file("tests", "test_import.xlsx", package = "xlsx")
#This works:
mccollect(mcparallel({
#Automatically initiates JVM in child
xlsx::read.xlsx(myfile, 1)
}))
然而,在我的情况下,问题是JVM已经在(主)父进程中启动了。这使得无法在子进程中使用rJava
:
#init JVM in parent
.jinit()
#Doesn't work anymore
mccollect(mcparallel({
xlsx::read.xlsx(myfile, 1)
}))
所以我真正需要的是在子进程中关闭/终止和重启JVM的方法。简单地detach("package:rJava", unload = TRUE)
似乎没有做到这一点。 force.init
参数似乎不会导致重启:
#Also doesn't work:
.jinit()
mccollect(mcparallel({
.jinit(force.init = TRUE)
xlsx::read.xlsx(myfile, 1)
}))
是否有某种方法可以强制关闭/终止JVM以便在子进程中重新启动它?
答案 0 :(得分:1)
有一种方法可以使用rJava并行运行表达式,基于运行并行进程来获取和汇总所有结果 BEFORE 在主进程中加载rJava库。由于主R进程尚未启动jvm,因此java在每个子进程中启动,并且此特定实例也将与子进程一起死亡。
# Rsession started
library(parallel)
myfile <- system.file("tests", "test_import.xlsx", package = "xlsx")
e <- expression({
require(rJava)
require(xlsx)
read.xlsx(myfile, 1)
})
p <- mcparallel(e)
q <- mcparallel(e)
pq <- mccollect(list(p, q))
# again to check reproducibility
p <- mcparallel(e)
q <- mcparallel(e)
pq2 <- mccollect(list(p, q))
identical(unname(pq),unname(pq2))
# see the result if it is the right content and not tryerr
pq
# now the main continues ...
# and if necessary even load rJava