我需要执行Reval
以多线程的方式,这是Rserve
提供得相当好。
但是,如果一个实例的评估时间太长,我需要能够关闭正在计算阻塞评估的实例。据我测试,给定的实例将拒绝关闭,直到评估完成(显然,它需要在再次监听之前获取结果)。所以这是我的问题:
有没有办法获得阻塞实例的java句柄(类似于Process
对象),这样我就可以强力杀死/终止评估(类似于process.destroy()
)?
换句话说,当我请求一个 eval(创建一个连接,抛出一个命令)时,如何通过 java 在正在处理的 eval 和与其相关的 Rsere 实例之间建立关系?
或者我是否错过了 Rserve 的某些功能,它已经可以满足此类需求?
Note:我已经尝试通过运行所有内容(所有评估)serverEval()
而不是常规的eval
,它在主实例上运行计算,但这当然不能令人满意,因为它只使用一个进程(主进程)。我可以杀死那个,但我的主要目标是能够单独关闭在单个实例上运行的阻塞评估。当然,保留我的 8 个 CPU 核心的优势,也就是说,保留并行性。否则就没有必要使用 Rserve(在这种情况下,JRI 引擎就足够了)。
Note:我想避免这种事情(thread https://stackoverflow.com/questions/21580654/rserve-multiple-instances-on-one-server),在不同的端口上处理主服务器本身的多个实例。那不是一个选择。
我已经尝试在 Rserve 的邮件列表上获取信息,但尚未得到答复。
我希望我的表述足够清楚,以便能够在这里得到答案或有用的评论。如果没有,请询问详情。非常感谢。
Edit:我也测试过RCaller http://code.google.com/p/rcaller/,它处理一个需要的尽可能多的 R 实例,但是,由于它将结果写入 XML 文件以便稍后从 java 端解析(并不像 Rserve 那样真正使用通信协议),所以对于我必须做的事情来说它太慢了履行...
好的,这可以通过这种方式完成(从一些好人那里得到的,他们最终在 Rserve devel 邮件列表上回答了我):
在运行的线程中eval
应该是阻塞或太长,并且假设 Rserve 已启动:
private RConnection rEngine = null;
private int rServePid = -1;
//...
// Keep an opened instance and store the related pid
RConnection rconn = new RConnection();
this.rServePid = rconn.eval("Sys.getpid()").asInteger();
this.rEngine = rconn;
LOG.info("Rserve: started instance with pid '" + this.rServePid + "'.");
//...
this.rEngine.eval("some consuming code...");
它允许跟踪与所述相关的实例的 pideval
(R 提供Sys.getpid()
).
然后停止/中止/取消,因为一个简单的this.rEngine.close()
不会停止服务器端正在处理的任务,而只会关闭连接,我们需要杀死目标Rserve实例。这可以通过调用来完成tools::pskill()
(或任何其他系统调用,例如可能kill -9 my_pid
(UNIX*),TASKKILL /PID my_pid /F
(Windows),...,取决于平台),显然来自上述线程之外的另一个线程(正在等待“eval 部分”返回):
// Terminate.
RConnection c2 = new RConnection();
// SIGTERM might not be understood everywhere: so using SIGKILL signal, as well.
c2.eval("tools::pskill("+ this.rServePid + ")");
c2.eval("tools::pskill("+ this.rServePid + ", tools::SIGKILL)");
c2.close();
LOG.info("Rserve: terminated instance with pid '" + this.rServePid + "'.");
这样做的好处是独立于平台。
希望这能有所帮助。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)