【问题标题】:Ruby force close IO.popen java processRuby 强制关闭 IO.popen java 进程
【发布时间】:2015-03-04 20:03:46
【问题描述】:

如何强制退出/杀死被 IO.popen("command", "r+") 盯着的 java 进程?

我正在运行一个脚本,一个来自 ruby​​ 的小型 Java 程序,执行以下操作:

pipe = IO.popen("nice -n 19 java -Xmx2g -Djava.awt.headless=true -jar java_program.jar", 'r+')

然后我使用 stdio 来回发送参数,如下所示:

pipe.puts "data"
result = pipe.gets

这适用于我发送的大多数数据,但对于某些 java 进程似乎锁定或什么的,我想强制关闭/终止 java 进程。

我目前正在执行以下操作,这似乎并没有杀死 java 进程(来自另一个监视这些东西的线程):

thepid = nil
thepid = pipe.pid            if pipe.respond_to?(:pid)
pipe.puts('')                if pipe.respond_to?(:puts) #This is the java_program's approach to closing, writing empty string to stdio will cause it to start it's shutdown procedure.
pipe.close                   if pipe.respond_to?(:close)
Process.kill('KILL', thepid) if thepid && Process.getpgid( thepid )

java 进程徘徊并拒绝死亡。我该怎么做才能真正强制进程退出(它使用大量内存:()

另外:是否有跨平台的方式来做到这一点?

【问题讨论】:

  • 你试过popen3吗?你的kill 电话的结果是什么?你确定你的目标是正确的PID吗?您可能正在杀死 nice 进程,而不是 java 进程。
  • popen3 会有什么不同吗?我对此了解不多。除了 3 个不同的 IO 之外,它的工作方式是否与普通的 popen 不同?

标签: ruby popen kill


【解决方案1】:

您可能在这里看到的是您正在杀死 nice 进程,而不是它启动的 java 进程。

您可以通过直接启动java 进程然后在获得的PID 上使用renice 更改nice 级别来避免这种情况。

检查您是否正在尝试终止正确的进程也是值得的。正如你所指出的,意外产生第二个实例意味着你杀错了。

popen3 这样的工具允许对子进程进行更多控制,并让您能够直接提供输入和捕获输出。

【讨论】:

  • 删除 nice 前缀没有帮助。还有其他想法吗?
  • 将您的进程列表与您捕获的pid 值进行比较。
  • 这是正确的。也许我使用了错误的信号? KILL 是最好使用的信号,还是我应该发送 TERM 或完全不同的东西?什么实际上会提前终止该进程?
  • KILL 是最极端的版本,不给进程关闭的机会,不容忽视。如果这不起作用,那么奇怪的事情正在发生。来自命令行的等效调用是否会产生任何有意义的错误?您确定触发了kill 调用吗?
  • 所以我重构了我的东西,是的,它解决了我的问题。我在关闭过程中遇到了竞争条件,导致新实例立即启动。为了解决这个问题,我从使用IO.popen/Open3.popen3 的非块版本到块版本。这让我的生活轻松了很多。您对“您确定您的目标是正确的 PID”的评论基本上是对此的答案。随意将其添加到答案中,我会接受:)
猜你喜欢
  • 2011-04-08
  • 2020-12-21
  • 1970-01-01
  • 1970-01-01
  • 2011-10-30
  • 2012-05-31
  • 2019-07-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多