Java - 对象运行外部进程: how to stop it?

标签 java

我有一个 Java 类(class)。它的构造函数调用 ProcessBuilder 类来运行外部问题(下面提供了完整的类代码,我认为其中对于我的问题没有什么重要的,但我给出它只是为了说明并使我的问题不那么抽象)。

我的代码运行良好,但是,当一切完成后,它不会停止。对我来说这似乎合乎逻辑,因为外部进程仍在运行。所以我找到了阻止它的方法。由于我的类刚刚启动它,我认为类实例和正在运行的外部进程之间没有“链接”,所以如果我销毁这个对象,外部进程仍然会运行。我的问题是:如何终止该外部进程?

我很抱歉问了一个愚蠢的问题,它必须在某个地方得到回答,但我找不到它。

非常感谢您抽出时间!

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()实现)

关于Java - 对象运行外部进程: how to stop it?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44900460/

相关文章:

Java:将 List<String> 转换为 join()d 字符串

java - Gradle Jacoco - 找不到方法 jacocoTestReport()

java - 是否可以将 DeviceCode 身份验证流程与 Azure Java SDK 一起使用?

java - 返回 Android 中的上一个 Activity

java - 撤消设置失败的错误

java - `Matchers.hasItem` 和 `Matchers.contains` 相同吗?

java - 我可以同时拥有 Spring Tool Suite 和 Eclipse 吗?

java - 如何在 JNA 中使用 C++ 对象

java - 在 android.widget.AbsListView.contentFits(AbsListView.java :722)

java - org.hibernate.MappingException : Could not determine type for: java. util.List,位于表 : user, 的列 : [org. hibernate.mapping.Column(events)]