Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/350.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Rserve服务器:如何终止一个阻塞实例(eval需要永远)?_Java_R_Process_Terminate_Rserve - Fatal编程技术网

Java Rserve服务器:如何终止一个阻塞实例(eval需要永远)?

Java Rserve服务器:如何终止一个阻塞实例(eval需要永远)?,java,r,process,terminate,rserve,Java,R,Process,Terminate,Rserve,我需要以多线程的方式执行Revals,这是Rserve提供的非常好的功能。 但是,如果一个实例的评估时间太长,我需要能够关闭正在计算阻塞评估的实例。据我测试,给定实例将拒绝关闭,直到完成评估(显然,它需要在再次侦听之前获取结果)。所以我的问题是: 有没有一种方法可以在阻塞实例(类似于进程对象)上获得java句柄,这样我就可以强行杀死/终止eval(类似于进程.destroy())? 换句话说,当我请求eval(创建连接、抛出命令)时,如何通过java在正在处理的eval和与其相关的Rsere实例

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

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

还是我错过了一些关于Rserve的东西,它已经允许处理这种需求

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

注意:我希望避免这种情况(),处理不同端口上主服务器本身的多个实例。这不是一个选择

我已经试着从Rserve的邮件列表中获取信息,但还没有得到回复。 我希望我说得够清楚,能在这里得到一个答案或有用的评论。如果没有,请询问详情。提前谢谢你


编辑:我也进行了测试,它可以处理所需的尽可能多的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
(R privides
Sys.getpid()
)相关的实例的pid

然后要停止/中止/取消,因为一个简单的
this.rEngine.close()
不会停止服务器端正在处理的任务,而只是关闭连接,我们需要终止目标Rserve实例。这可以通过调用
工具::pskill()
(或者任何其他系统调用,如
kill-9 my\u pid
(UNIX*)来完成,
TASKKILL/PID my_PID/F
(Windows),…,这取决于平台),显然是来自上述线程以外的另一个线程(正在等待“eval部分”返回):

这样做的好处是平台独立

希望这能有所帮助。

怎么样

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

它将返回运行Rserve的pid(不是主pid),然后您可以使用此pid终止它。

这是可行的。但是如果我尝试类似于
rEngine=new RConnection();//获取rEngine的pid并使用rEngine进行耗时的评估。//终止RConnection c2=new RConnection();//SIGTERM可能不是到处都能理解的:因此也可以使用SIGKILL信号。c2.eval(“tools::pskill”(+this.rServePid+);c2.eval(“tools::pskill”(+this.rServePid+”,tools::SIGKILL)”;c2.close();
,进程被终止,但Rserve的cpu使用率上升,并且Rserver不允许任何新连接。你知道为什么吗?听起来像是最新的
eval
没有返回并继续占据整个核心。在某些情况下,你必须获得整个进程树(需要终止父进程才能真正关闭它)。当然,这种方法依赖于平台。我有Windows/OSX和NUX批处理脚本(系统调用)。如果您需要更具体的资料,请告诉我。干杯。我不想杀死整个进程树。其他人将在同一个服务器上工作,杀死整个进程也将杀死他们的实例。但问题不在于eval。eval返回,代码执行移到下一行。但cpu使用率在杀死时达到峰值一个实例。好的,我明白了。所以它让计算机忙了一段时间。一切都冻结了吗?或者尝试新连接在某个点上成功了吗?坦白地说,我看不出有什么原因,除非你将你的“杀手连接”寻址到一个已经很忙的Rserve服务器。注意:Rserve不能像它一样在windows下生成子连接因此,如果您在Windows下工作,您可能必须处理多个Rserve实例。例如,请参阅此Rserve包装中的处理方式(如果我在其中,我将使用此包装:。查看如何在Windows下模拟生成实例。顺便问一句,您的操作系统是什么?
rcon.eval("system(\"echo $$\", intern = TRUE)");