优雅地终止 Apache Commons Exec 进程

发布于 2024-10-20 04:19:11 字数 207 浏览 4 评论 0原文

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

I am starting an external process in my Java program (on Linux) and I need the ability to send it a SIGTERM signal rather than the SIGKILL that exec.getWatchdog().destroyProcess() is sending. Is there a way that I can more gracefully stop a unix process started with commons-exec? Or can I get the PID so that I can just run the appropriate kill command myself?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

岁月如刀 2024-10-27 04:19:11

ExecuteWatchdog 类具有终止进程的方法。

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

executor.getWatchdog().destroyProcess();

ExecuteWatchdog class has method for killing process.

So, you could just create a watchdog with long timeout and use it to kill process when neccessary, i.e.

executor.getWatchdog().destroyProcess();
如歌彻婉言 2024-10-27 04:19:11

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

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

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

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

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

Well, Commons Exec relies on the Java Process class, which doesn't expose a PID. It's also what is used to kill the process, so it's not something you can change the behavior of. All nice and encapsulated. Gotta love OO, eh?

If you are simply launching processes in to the background, you can wrap them in a simple shell script that captures the PID for you, and then saves that off to a "known place" that your Java routine knows about. Still kind of messy, and, naturally, it doesn't port to other platforms well.

You can write your own exec function using JNI to capture this information for you as well, but that's likely less friendly.

You could write a platform specific exec launcher daemon in something more system oriented (C, Python, etc.). You send IT messages to launch and stop things, and it handles that process for you. One benefit of this is that you don't have to fork the JVM when you run a new process (which can be quite expensive depending on your JVM size).

You can start the daemon up at the beginning and share a socket or a pipe (both pretty portable). That's actually not a horribly INelegant solution, and it compartmentalizes a lot of system specific behavior (so you can have a completely different process on, say, Windows vs Unix and your Java stays the same, you just need to port your little daemon), without having to run JNI.

掩耳倾听 2024-10-27 04:19:11

好吧,你可以 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号。

Well you could grep it, for ex :

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

This is in case that you have it running more than 1 time(although it works if you have just one project), notice the [] in grep, that is so the grep doesn't give you its own process pid and -i stands for ignore case, awk is for printing second column only that is PID number.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文