3

我有一个我正在创建的 r 代码,我想检测 Windows 中运行的 R 实例的数量,以便脚本可以选择是否运行一组特定的脚本(即,如果已经有 >2 个 R 实例运行做 X,否则 Y)。

有没有办法在 R 中做到这一点?

编辑:这里有一些关于目的的信息:我有一套很长的脚本,用于使用 catnet 库应用贝叶斯网络模型,用于数千个案例。此代码处理每个案例的结果并将结果输出为一个 csv 文件。我尝试过的大多数并行计算替代方案并不理想,因为它们抑制了许多内置的进度通知,因此我一直在 R 的不同实例上运行案例的子集。我知道这有点过时了,但它对我有用,所以我想要一种方法让代码子集根据运行的实例数自动计算案例数。我现在通过在 CMD 中打开多个 Rscript 实例来手动执行此操作,打开配置略有不同的 r 文件以获得如下内容: 在此处输入图像描述

cd "Y:\code\BN_code"
START "" "C:\Program Files\R\R-3.0.0\bin\x64\Rscript.exe" "process spp data3.r" /b
START "" "C:\Program Files\R\R-3.0.0\bin\x64\Rscript.exe" "process spp data3_T1.r" /b
START "" "C:\Program Files\R\R-3.0.0\bin\x64\Rscript.exe" "process spp data3_T2.r" /b
START "" "C:\Program Files\R\R-3.0.0\bin\x64\Rscript.exe" "process spp data3_T3.r" /b

编辑2:

感谢下面的答案,这是我在 R 中所谓的“穷人并行计算”的实现:因此,如果您有任何长脚本必须应用于一长串案例,请使用下面的代码将长列表分解为要馈送到 rscript 的每个实例的子列表的数量:

#the cases that I need to apply my code to:
splist=c("sp01", "sp02", "sp03", "sp04", "sp05", "sp06", "sp07", "sp08", "sp09", "sp010", "sp11", "sp12", 
         "sp013", "sp014", "sp015", "sp16", "sp17", "sp018", "sp19", "sp20", "sp21", "sp22", "sp23", "sp24")
###automatic subsetting of cases based on number of running instances of r script:
cpucores=as.integer(Sys.getenv('NUMBER_OF_PROCESSORS'))
n_instances=length(system('tasklist /FI "IMAGENAME eq Rscript.exe" ', intern = TRUE))-3
jnk=length(system('tasklist /FI "IMAGENAME eq rstudio.exe" ', intern = TRUE))-3
if (jnk>0)rstudiorun=TRUE else rstudiorun=FALSE 

if (!rstudiorun & n_instances>0 & cpucores>1){ #if code is being run from rscript and 
#not from rstudio and there is more than one core available
  jnkn=length(splist)
  jnk=seq(1,jnkn,round(jnkn/cpucores,0))
  jnk=c(jnk,jnkn)
  splist=splist[jnk[n_instances]:jnk[n_instances+1]]
}
###end automatic subsetting of cases

#perform your script on subset of list of cases:
for(sp in splist){
  ptm0 <- proc.time()
  Sys.sleep(6)  
  ptm1=proc.time() - ptm0
  jnk=as.numeric(ptm1[3])
  cat('\n','It took ', jnk, "seconds to do species", sp)
}

要使此代码在 Windows 中自动在多个 r 实例上运行,只需创建一个 .bat 文件:

cd "C:\Users\lfortini\code\misc code\misc r code"
START "" "C:\Program Files\R\R-3.0.0\bin\x64\Rscript.exe" "rscript_multiple_instances.r" /b
timeout 10
START "" "C:\Program Files\R\R-3.0.0\bin\x64\Rscript.exe" "rscript_multiple_instances.r" /b
timeout 10
START "" "C:\Program Files\R\R-3.0.0\bin\x64\Rscript.exe" "rscript_multiple_instances.r" /b
timeout 10
START "" "C:\Program Files\R\R-3.0.0\bin\x64\Rscript.exe" "rscript_multiple_instances.r" /b
exit

超时是为了给 r 足够的时间来检测它自己的实例数量。单击此 .bat 文件将自动打开许多 r 脚本实例,每个实例都处理您要分析的案例的特定子集,同时仍会在每个窗口中提供脚本运行的所有进度,例如上图。这种方法很酷的一点是,您几乎只需在代码中使用的任何迭代机制(循环、应用 fx 等)之前添加自动列表子集代码。然后只需使用 .bat 或手动使用 rcript 触发代码,您就可以设置了。

4

2 回答 2

8

实际上,这比预期的要容易,因为 Windows 带有在这里tasklist找到的不错的功能。

有了它,您可以获取所有正在运行的进程,您只需计算Rscript.exe实例的数量(我stringr在这里用于字符串操作)。

require(stringr)
progs <- system("tasklist", intern = TRUE)
progs <- vapply(str_split(progs, "[[:space:]]"), "[[", "", i = 1)
sum(progs == "Rscript.exe")

这应该够了吧。(我只尝试过计数实例,Rgui.exe但效果很好。)

于 2013-04-10T23:14:45.190 回答
4

你可以做的更短如下

length(grep("rstudio\\.exe", system("tasklist", intern = TRUE)))

替换rstudio为任何其他Rscript或任何其他进程名称

甚至更短

length(system('tasklist /FI "IMAGENAME eq Rscript.exe" ', intern = TRUE))-3

于 2013-04-11T02:34:14.650 回答