1

我正在开发一个应用程序,允许用户在服务器上远程运行 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 中是否有办法获取给定进程的句柄?看起来不像。

- 编辑

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

4

3 回答 3

2

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

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

于 2013-01-15T19:47:58.247 回答
1

我终于找到了一个安全的解决方案。在 restful java 服务中,usingProcess p = Runtime.getRuntime().exec()为您提供了正在运行的进程的句柄。然而,获得 pid 的唯一方法是通过一种称为反射的技术。

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

尴尬到不可思议……

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

于 2013-01-16T19:33:37.727 回答
0

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

或者看看Get subprocess id in Java

于 2013-01-15T20:21:04.633 回答