使用Java的ProcessBuilder
我正在创建一组子进程。我可以使用生成的waitFor()
对象中的Process
方法等待该特定子项退出。
是否可以阻止任何子进程以UNIX wait()
系统调用的方式退出?
答案 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)
使用a初始化CountDownLatch 给定数量。 await方法块 直到当前计数达到零 由于countDown()的调用 方法,之后全部等待 线程被释放,任何 随后的等待返回调用 立即。这是一次性的 现象 - 计数不可能 重启。如果你需要一个版本 重置计数,考虑使用a 的CyclicBarrier。
答案 2 :(得分:-2)
你必须使用某种形式的IPC来实现这一目标。如果您被允许使用本机库,并且如果您在UNIX / Linux平台上工作,请尝试使用相同的wait()系统调用,方法是编写一个简单的JNI包装器和放大器。从java代码调用本机方法。
如果您不能使用本机IPC机制,请使用TCP / IP服务器/客户端机制,在客户端连接/断开服务器连接时,您可以控制子进程从服务器退出。如果没有子连接,您可以退出服务器程序!