Java,等待子进程退出

时间:2011-01-07 05:10:58

标签: java child-process

使用Java的ProcessBuilder我正在创建一组子进程。我可以使用生成的waitFor()对象中的Process方法等待该特定子项退出。

是否可以阻止任何子进程以UNIX wait()系统调用的方式退出?

3 个答案:

答案 0 :(得分:9)

第一步是将每个子流程完成的工作表示为Future,如下所示:

final ProcessBuilder builder = ...;

// for each process you're going to launch
FutureTask task = new FutureTask(new Callable<Integer>() {
  @Override public Integer call() {
    return builder.start().waitFor();
  }
};

现在将所有任务提交给执行者:

ExecutorService executor = Executors.newCachedThreadPool();
for (FutureTask task : tasks) {
  executor.submit(task);
}

// no more tasks are going to be submitted, this will let the executor clean up its threads
executor.shutdown();

现在使用优秀的ExecutorCompletionService类:

ExecutorCompletionService service = new ExecutorCompletionService(executor);
while (!executor.isTerminated()) {
  Future<Integer> finishedFuture = service.take();
  System.out.println("Finishing process returned " + finishedFuture.get());
}

此循环将在完成每个完成任务时迭代一次。 returnValue将是子进程的退出代码。

现在,您还不确切知道哪个进程已完成。你可以改变Callable而不是返回一个Integer来返回Process,或者更好的是你自己的一个类来表示进程的输出。

哦,当然,如果您不关心等待所有任务,您只需拨打take()一次。

答案 1 :(得分:0)

了解CountDownLatch

  

使用a初始化CountDownLatch   给定数量。 await方法块   直到当前计数达到零   由于countDown()的调用   方法,之后全部等待   线程被释放,任何   随后的等待返回调用   立即。这是一次性的   现象 - 计数不可能   重启。如果你需要一个版本   重置计数,考虑使用a   的CyclicBarrier。

答案 2 :(得分:-2)

你必须使用某种形式的IPC来实现这一目标。如果您被允许使用本机库,并且如果您在UNIX / Linux平台上工作,请尝试使用相同的wait()系统调用,方法是编写一个简单的JNI包装器和放大器。从java代码调用本机方法。

如果您不能使用本机IPC机制,请使用TCP / IP服务器/客户端机制,在客户端连接/断开服务器连接时,您可以控制子进程从服务器退出。如果没有子连接,您可以退出服务器程序!