6

我正在我的 Java 程序(在 Linux 上)中启动一个外部进程,我需要能够向它发送一个 SIGTERM 信号而不是exec.getWatchdog().destroyProcess()发送的 SIGKILL。有没有一种方法可以更优雅地停止以 commons-exec 启动的 unix 进程?或者我可以获取 PID,以便我可以自己运行适当的 kill 命令?

4

3 回答 3

8

ExecuteWatchdog 类有杀死进程的方法。

因此,您可以创建一个超时时间较长的看门狗,并在必要时使用它来终止进程,即

executor.getWatchdog().destroyProcess();
于 2012-09-18T15:34:12.967 回答
7

嗯,Commons Exec 依赖于 Java Process 类,它不公开 PID。它也是用来杀死进程的东西,所以它不是你可以改变行为的东西。一切都很好,封装。一定要爱OO,嗯?

如果您只是在后台启动进程,您可以将它们包装在一个简单的 shell 脚本中,该脚本为您捕获 PID,然后将其保存到您的 Java 例程知道的“已知位置”。仍然有点乱,而且,自然地,它不能很好地移植到其他平台。

您也可以使用 JNI 编写自己的 exec 函数来为您捕获此信息,但这可能不太友好。

您可以使用更面向系统(C、Python 等)的方式编写特定于平台的 exec 启动程序守护程序。您发送 IT 消息以启动和停止事物,它会为您处理该过程。这样做的一个好处是您不必在运行新进程时分叉 JVM(这可能会非常昂贵,具体取决于您的 JVM 大小)。

您可以从一开始就启动守护程序并共享一个套接字或管道(两者都非常便携)。这实际上不是一个可怕的 Inelegant 解决方案,它划分了许多系统特定的行为(所以你可以在 Windows 和 Unix 上拥有完全不同的进程,而你的 Java 保持不变,你只需要移植你的小守护进程),无需运行 JNI。

于 2011-03-02T23:25:01.450 回答
0

那么你可以grep它,例如:

for i in $(ps -ef | grep -i "[Y]ourClassName" | awk '{print $2}'); do kill -9 $i; done

如果您让它运行超过 1 次(尽管如果您只有一个项目,它可以工作),请注意 grep 中的 [],这样 grep 不会给您自己的进程 pid 并且 -i 代表对于忽略大小写,awk 仅用于打印第二列,即 PID 编号。

于 2011-03-02T22:48:23.533 回答