【问题标题】:How to know when a Runtime.exec() process is stuck, programatically?如何以编程方式知道 Runtime.exec() 进程何时卡住?
【发布时间】:2016-09-01 07:04:04
【问题描述】:

我正在 unix 服务器中使用 Process 执行一些 pl/sql 文件。下面是代码

String line;
Process p = null;

p = Runtime.getRuntime().exec("sqlplus -s " + USER + "/" + PASS + "@" + sid + " @" + sqlTempDirectory);

BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
        if (line.contains("invalid username/password")) {
            System.out.println(sql.getName() + " file creation skipped as invalid username/password");
            p.destroy();
            break;
        }
}
input.close();

问题: 这个java.lang.Process 有时会因为无效的用户名/密码、找不到文件或可能是一些未知的异常而被击中。现在,根据我正在捕获的输入流数据异常并使用p.destroy(). 销毁进程但这仅涵盖我知道的异常,不包括可能发生的任何其他异常。

问题:我怎样才能确定进程是否被触发?如果它被击中,那么我想摧毁java.lang.Process

编辑检查线程的活动可能不是解决方案,因为在我连接到数据库的情况下。因此,该过程可能会等待数据库连接并在连接建立时恢复,这可能需要一些时间。我正在实时服务器实例中运行代码,因此可能会发生等待。这并不能证明该进程已死。我想确定进程何时陷入僵局并且不会在未来的任何时候恢复。

编辑 2: 我不想杀死整个 java 程序的执行。我只想摧毁那个特定的java.lang.Process。所以解决方案必须是一些 java 代码,它会破坏 java.lang.Process 并继续执行程序的其余部分。

编辑 3: 问题不重复,因为我需要 Java 方式。获取线程转储将无济于事。我只想销毁java.lang.Process,而不是完整的java程序执行。

主要问题:我应该什么时候终止我的进程。

不是如何,而是何时。我不想申请超时,因为我将在一些实时实例中运行程序,并且可能有许多其他外部原因导致进程卡住并且进程可能有机会恢复。但如果出现异常,该过程将不会恢复。我想处理这些场景。 输入流是空的,所以不知道是否发生错误。

【问题讨论】:

  • 另请参阅When Runtime.exec() won't,了解有关正确创建和处理流程的许多好技巧。然后忽略它引用exec 并使用ProcessBuilder 创建进程。还将String arg 拆分为String[] args 以解决包含空格字符的路径之类的问题。
  • @DannyChen 它没有回答我的问题。我有特定的 sql 文件。因此,继续检查该线程以查看活动可能没有帮助。可能是该进程正在等待数据库连接,并且可能会在一段时间后恢复。所以基于时间杀死一个进程并不是一个解决方案。我想确定进程是死锁的,不会进一步执行。
  • 这里没有死锁的证据。不要滥用标准术语。
  • @EJP 好的,很抱歉造成混乱......但问题仍然没有得到回答,我怎么知道这个过程是否会导致某些事情或在提到异常的情况下保持原样。我正面临这个问题,因为在执行该过程后几个小时都没有发生任何事情。甚至输入流也是空的。我不想申请超时,因为我将在一些实时实例中运行程序,并且可能有许多其他外部原因导致进程卡住并且进程可能有机会恢复。但如果出现异常,该过程将不会恢复。我想处理那些场景
  • @HarshitaSethi 从理论上确定任意给定程序是否会结束被称为“停止问题”,并且已证明没有算法可以决定这一点。我是您的特殊情况,只有您知道问题的含义以及是否可以检查它是否有任何进展,因此只有您可以判断是否有办法判断程序是否卡住了。

标签: java runtime.exec


【解决方案1】:

你的意思是卡住了吗?通过 jconsole 等 jvm 监控工具观察到卡住的线程。如果你想根据一些异常和/或运行时错误来停止操作系统进程,你可以简单地将你的代码包装在 catch 块中

try {
        //process initiation
    } catch (Exception e) {
        //attempt process stop
    }catch(Error ex){
        //attempt process stop
    }

启动操作系统进程高度依赖于系统。如果您想尝试停止 os 进程,如果它花费的时间比您预期的要长,您可以在一个可以指定超时的线程中启动该进程。

【讨论】:

  • 卡住的意思是我使用Runtime.exec() 执行一个文件,但它什么也没做。由于某种原因,它被阻止了。我看不到原因。没有例外,但是进程被阻塞了,这是一个死锁。
  • @HarshitaSethi 块不是死锁。它是一个块。死锁是有两个进程和两个锁(或更多)的地方。这是一个块。不要滥用标准术语。
猜你喜欢
  • 1970-01-01
  • 2014-03-22
  • 2020-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-20
  • 2011-02-17
相关资源
最近更新 更多