Rserve服务器:如何终止阻塞实例(eval永远消失)?

Gau*_*lio 6 java r process terminate rserve

我需要以eval多线程方式执行R s,这是Rserve非常好的.但是,如果一个实例的eval需要太长时间,我需要能够关闭计算阻塞eval的实例.就我测试而言,给定的实例将拒绝关闭直到eval完成(显然,它需要在再次侦听之前获取结果).所以这是我的问题:

有没有办法在阻塞实例(类似Process对象)上获取java句柄,这样我就可以强行杀死/终止eval(类似的东西process.destroy())?换句话说,当我要求eval(创建连接,抛出命令)时,如何通过java在正在处理的eval和与之相关的Rsere实例之间建立关系?

或者我是否错过了一些已经允许处理这种需求的Rserve?

注意:我已经尝试运行所有(所有evals)serverEval()而不是常规eval,它运行主实例上的计算,但这当然不满意,因为它只使用一个进程(主要进程).那个我可以杀死的,但我的主要目标是能够单独关闭一个阻塞的eval,在一个单独的实例上运行.而且,自然地,保持我的8个CPU内核的优势,也就是说,保持并行性.除此之外没有必要使用Rserve(在这种情况下JRI引擎就足够了).

注意:我想避免这种事情(线程),在不同的端口上处理主服务器本身的几个实例.这不是一种选择.

我已经尝试获取有关Rserve邮件列表的信息,但尚未得到答复.我希望自己能够清楚地在这里得到答案或有用的评论.如果没有,请询​​问详情.非常感谢提前.

编辑:我还测试了RCaller,它处理R需要的任意数量的实例,但是,因为它将结果写入XML文件以便稍后从java端解析(不像Rserve那样真正使用通信协议),它也是我必须执行的速度慢...

Gau*_*lio 6

好的,这可以通过这种方式完成(从最终在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...");
Run Code Online (Sandbox Code Playgroud)

这允许跟踪与所述eval(R privides Sys.getpid())相关的实例的pid .

然后停止/中止/取消,因为简单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 + "'.");
Run Code Online (Sandbox Code Playgroud)

那个人有利于平台独立.

希望这可以提供帮助.