Java - 对象运行一个外部进程:如何阻止它?
我有一个Java类。它的构造函数调用ProcessBuilder
类来运行一个外部问题(下面提供了完整的类代码,我认为对于我的问题没有什么重要的内容,但我只是为了说明问题而不是抽象)。Java - 对象运行一个外部进程:如何阻止它?
但是,当我的代码运行良好时,一切都完成了,它不会停止。这对我来说似乎合乎逻辑,因为外部过程仍在运行。所以我找到了如何阻止它的方法。当我的类刚开始时,我认为类实例和正在运行的外部进程之间没有“连接”,所以如果我销毁这个对象,外部进程仍然会运行。我的问题是:我怎样才能杀死这个外部进程?
对于一个愚蠢的问题,我很抱歉,它必须在某个地方回答,但我找不到它。
非常感谢您的时间!
public static class OptimizerMOEA extends ExternalProblem {
public static final String SEPARATOR = "\\s+"; //a space
public static final float LOWER_BOUND = 0.0;
public static final float UPPER_BOUND = 275000000*3;
public static final String CPP_EXE_NAME = "optimizer_moea";
public OptimizerMOEA() throws IOException{
super(CPP_EXE_NAME);
}
public OptimizerMOEA(String path) throws IOException{
super(path);
}
@Override
public String getName() {
return "OptimizerMOEA";
}
@Override
public int getNumberOfVariables() {
//!!! TODO: pass this value from C++ function to this class
return 6890;
}
@Override
public int getNumberOfObjectives() {
return 2;
}
@Override
public int getNumberOfConstraints() {
return 0;
}
@Override
public Solution newSolution() {
Solution solution = new Solution(getNumberOfVariables(),
getNumberOfObjectives());
for (int i = 0; i < getNumberOfVariables(); i++) {
solution.setVariable(i, new RealVariable(LOWER_BOUND, UPPER_BOUND));
}
return solution;
}
}//EOF OptimizerMOEA class
编辑:
这是我用的是父类的构造函数:
/**
* Constructs an external problem using {@code new
* ProcessBuilder(command).start()}. If the command contains arguments,
* the arguments should be passed in as separate strings, such as
* <pre>
* new ExternalProblem("command", "arg1", "arg2");
* </pre>
*
* @param command a specified system command
* @throws IOException if an I/O error occured
*/
public ExternalProblem(String... command) throws IOException {
this(new ProcessBuilder(command).start());
}
而这些都是其他的构造。我的Java类通过标准I/O与外部进程通信。所以使用套接字的构造函数只是为了完整性而给出的。
也许在参数中使用带有进程的构造函数是一个解决方案。在这种情况下,如果有一种方法可以解决第一个构造函数的问题,我仍然感兴趣(仅仅因为我没有看到它,发现它是一个有趣的问题,我想知道在这种情况下,这个构造函数可能是有用的,为什么)。
/**
* Constructs an external problem that connects to a remote process via
* sockets. The remote process should be instantiated and already
* listening to the designated port number prior to invoking this
* constructor.
*
* @param host the host name of the remote system; or {@code null} to use
* the local host
* @param port the port number
* @throws UnknownHostException if the IP address of the specified host
* could not be determined
* @throws IOException if an I/O error occurred
*/
public ExternalProblem(String host, int port) throws IOException,
UnknownHostException {
this(new Socket(host, port));
}
/**
* Constructs an external problem that connects to a remote process via
* sockets. The remote process should be instantiated and already
* listening to the designated port number prior to invoking this
* constructor.
*
* @param address the IP address of the remote system
* @param port the port number
* @throws IOException if an I/O error occurred
*/
public ExternalProblem(InetAddress address, int port) throws IOException {
this(new Socket(address, port));
}
/**
* Constructs an external problem using the specified socket.
*
* @param socket the socket used to send solutions to be evaluated
* @throws IOException if an I/O error occurred
*/
ExternalProblem(Socket socket) throws IOException {
this(socket.getInputStream(), socket.getOutputStream());
}
/**
* Constructs an external problem using the specified process.
*
* @param process the process used to evaluate solutions
*/
ExternalProblem(Process process) {
this(process.getInputStream(), process.getOutputStream());
RedirectStream.redirect(process.getErrorStream(), System.err);
}
/**
* Constructs an external problem using the specified input and output
* streams.
*
* @param input the input stream
* @param output the output stream
*/
ExternalProblem(InputStream input, OutputStream output) {
super();
reader = new BufferedReader(new InputStreamReader(input));
writer = new BufferedWriter(new OutputStreamWriter(output));
}
此:
new ProcessBuilder(command).start();
返回Process
对象,如果你持有对它的引用,你可以在以后的时间打电话Process.destroy()
(this SO answer详细介绍了destroy()
实现)
谢谢!如果我明白了,如果我没有参考(“令人惊讶的”),那么就没有办法销毁它......这实际上是我的问题,尽管我认为这是不可能的。 – kilpikonna
是的。这是正确的 –
有在你的代码中没有''ProcessBuilder''。我怀疑真正的工作是在你延续的课程中完成的。 – f1sh
是的,就是这样,我如何说(但也许它不清楚) - 父类的构造函数调用ProcessBuilder。 – kilpikonna
“Process”的停止必须以某种方式在父类中完成。它应该在启动后保留'Process'实例,并且必须能够使用Process.destroy()来停止它。 – kalsowerus