2017-07-04 69 views
1

我有一個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)); 
} 
+0

有在你的代碼中沒有''ProcessBuilder''。我懷疑真正的工作是在你延續的課程中完成的。 – f1sh

+0

是的,就是這樣,我如何說(但也許它不清楚) - 父類的構造函數調用ProcessBuilder。 – kilpikonna

+0

「Process」的停止必須以某種方式在父類中完成。它應該在啓動後保留'Process'實例,並且必須能夠使用Process.destroy()來停止它。 – kalsowerus

回答

2

此:

new ProcessBuilder(command).start(); 

返回Process對象,如果你持有對它的引用,你可以在以後的時間打電話Process.destroy()this SO answer詳細介紹了destroy()實現)

+0

謝謝!如果我明白了,如果我沒有參考(「令人驚訝的」),那麼就沒有辦法銷燬它......這實際上是我的問題,儘管我認爲這是不可能的。 – kilpikonna

+0

是的。這是正確的 –