我试图在R中设置异步系统()调用。为了使它有用,用户需要一种方法来检查进程是否已经结束。问题是如何测试?在how to run an executable file and then later kill or terminate the same process with R in Windows中,建议似乎是捕获system()调用之前和之后的所有pid以获取刚刚启动的进程的pid(然后可以用它来测试它是否具有结束),但这似乎是一种容易出错的方式,除了它依赖于操作系统......
是否存在解决此问题的其他方法(不必涉及pid')
编辑:当前场景应该用于:
我正在开发一个Shiny GUI,它可以处理用Java实现的可能非常长时间运行的计算。计算是分批完成的,在这些运行期间,即使R处于空闲状态,GUI也会在等待Java进程完成时被锁定与R服务器进行交互。我想要一种方法来启动Java进程而不是等待它完成(使用wait = FALSE参数),但是有一种故障安全方式来检查它是否已经完成,因此可以相应地更新GUI ... < / p>
答案 0 :(得分:0)
如果我们愿意调用系统来启动一个进程,那么这个问题似乎简化了如何将PID转换为Windows中刚刚启动的进程。这不是R特定的问题,而是Windows的一般问题。在SO上查看一些答案,我看到one answer that seems reasonable。处理字符串结果,并获得PID。
或者,您可以使用system(...,wait = FALSE)异步启动另一个Rscript,并让它将自己的PID报告回主机进程(通过文件或套接字)。 Rscript可以反过来进行系统调用,然后在系统调用完成后自行终止。然后你只需要观察包装Rscript的PID。这比锁定文件略好,因为您不必依赖已调用的进程来成功完成清理自己的锁定文件。
我对agstudy的解决方案有一些例外(即使它是关键的)。正如ThomasP85所说,你可以通过系统获得异步操作(...,wait = FALSE)。此外,您可以通过套接字获得异步操作,例如svSocket
和parallel
(通过单个节点PSOCK群集)。这些基于套接字的方法中没有任何内容与通过rpy2在python中启动的上述延迟调用的基本不同完成。
答案 1 :(得分:-2)
R甚至不支持多线程系统。所以异步调用它并不是一件容易的事。一种方法是使用支持异步调用的语言调用它。例如python:
这是一个完整的示例,它异步调用2个R函数:
这是一个虚拟的例子,但它足够灵活,可以扩展到任何R脚本。
from twisted.internet.defer import Deferred
from twisted.internet import reactor
import rpy2.robjects as robjects
## define the functions
def get_perimeter(r):
robjects.r('''
f <- function(r) {
Sys.sleep(sample(1:3,1))
2 * pi * r
}
''')
r_f = robjects.r['f']
print r_f(r)
return r_f(r)
def get_radius(p):
robjects.r('''
f <- function(p) p/2 / pi
''')
r_f = robjects.r['f']
print r_f(p)
return r_f(p)
def job_done(_):
from twisted.internet import reactor
reactor.stop()
## the asynchronous call
d = Deferred()
d.addCallback(get_perimeter)
d.addCallback(get_radius)
d.addCallback(job_done)
reactor.callWhenRunning(d.callback, 25410)
reactor.run()