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

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

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

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

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

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

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

编辑:我还测试了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..."); 

这允许跟踪与所述eval相关的实例的pid(R privides 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 + "'."); 

那个人有利于平台独立。

希望这可以提供帮助。

怎么样

 rcon.eval("system(\"echo $$\", intern = TRUE)"); 

它将返回运行Rserve(不是主要)的pid然后你可以使用这个pid杀死它。