长时间运行进程远程终止?

时间:2013-01-15 19:13:54

标签: linux shell unix process pid

我正在开发一个允许用户远程在服务器上运行AI算法的应用程序。其中一些算法需要很长时间。它的设置使得AJAX调用提供算法参数并在服务器上启动C ++算法。通过AJAX调用轮询状态文件跟踪计算的结果和状态。此解决方案似乎适用于同时使用该服务的多个用户,但我现在正在寻找一种从用户的浏览器取消计算的方法。我有一个停止按钮,停止AJAX更新服务,并停止浏览器和服务器上正在运行的进程之间的任何通信。问题是该进程仍在运行,我想在用户取消操作时释放服务器资源。以下是一些更多细节。

AJAX调用命中的Web服务在用户'tomcat'下运行,可以通过ps -U tomcat列出。算法执行都是'java'的子进程,可以由ps --ppid ###列出。

浏览器记录当前计算开始的时间(用户系统时间,而不是服务器系统时间)。

从不同位置连接的用户可能会同时进行多次计算,从而导致许多进程具有相同的名称和父进程。

restful服务通过java runtime.exec()执行终端命令。

我不太了解shell脚本,因此非常感谢任何帮助。任何人都可以想办法使用java进程对象或shell脚本/ awk通过timestamp定位进程(可能是用户系统时间最近的时间戳......?)或其他方式?

提前致谢。

- 修改

如果你有pid,是否有一种方法可以让java获取给定进程的句柄?看起来不像。

- 修改

我无法更改服务器上长时间运行进程的源代码。 :(

3 个答案:

答案 0 :(得分:2)

您的AJAX调用应该操纵某种资源(最方便的是文本文件),该资源充当流程的semaphore,在每次轮询迭代中检查该信号量文件是否已设置为停止状态。如果AJAX将信号量文件更改为停止,则该过程将停止,因为您的应用程序会检查它并相应地做出响应。这反过来意味着需要将功能编程到Java AI应用程序中,而不是弄清楚PID是什么,然后在操作系统级别将其杀死。当然,这假设您可以访问应用程序的源代码。

当然,信号量不一定是文件,但可以是DB等中的值,以适合您的口味和配置为准。

答案 1 :(得分:1)

我终于找到了一个安全的解决方案。从restful java服务中,使用Process p = Runtime.getRuntime().exec()可以处理正在运行的进程。然而,获得pid的唯一方法是通过一种称为反射的技术。

Field f = p.getClass().getDeclaredField();
f.setAccessible(true);
String pid = Integer.toString(f.getInt(p));

多么令人难以置信的尴尬...

无论如何,由于p从服务器传递到客户端是不可能的,并且允许远程调用通过参数传递的pid杀死任意服务器进程的不安全性,我可以想出的唯一逻辑策略是将获取的pid写入由初始客户端时间戳指示的进程唯一文件,并在返回休息服务函数时删除此文件。此唯一文件可以通过另一个读取文件的restful服务用作终止句柄,并使用等于文件内容的pid终止进程。此

答案 2 :(得分:0)

您可以保留Process返回的runtime.exec实例,并调用Process.destroy来终止子进程。我不太了解您的Web服务应用程序,我认为您可以将流程实例保存在将用户映射到流程列表的全局会话映射中。确保访问此映射是线程安全的。此外,只有当您有一个允许跨不同请求共享此类全局会话映射的Web服务进程时,它才有效。

或者看看Get subprocess id in Java