parent 进程和 child 进程之间的通信
communication between a parent process and a child process
我有一个 class 作为 parent 进程。在其 运行 期间,它创建了许多 child 进程并同时 运行s 它们。每个 child 进程基本上都是一个连接到服务并从中提取数据的 HTTP 客户端。
目前,如果 child 进程之一因任何原因停止工作,parent 通过重新启动同一个 child 进程来处理 re-establishing 连接。
child 进程断开连接可能是由多种原因引起的。我想将 child 进程断开连接的原因传达给 parent 进程,并让 parent 进程根据断开连接的原因(套接字读取失败,404 未找到)采取相应行动, 401 未经授权等)。
可能吗? shortest/best 的方法是什么?
这是我的 Parent class:
public class Parent {
public static void main(String[] args){
List<Process> PRlist = new ArrayList<Process>();
List<String[]> commandsList = new ArrayList<String[]>();
DateTimeFormatter frmt = DateTimeFormatter.ofPattern("hh:mm:ss");
if (args.length == 2 && args[0].matches("-f")){
String dir = System.getProperty("user.dir");
String path = dir + "/" + args[1];
try {
FileReader fr = new FileReader(path);
BufferedReader bf = new BufferedReader(fr);
String line = "";
while ((line = bf.readLine()) != null){
String[] tk = line.split(" ");
String[] cmd = {"java", "-jar", "Child.jar", "-a", tk[0], "-p", tk[1],
"-u", tk[2], "-pw", tk[3], "-m", tk[4], "-s", tk[5]};
Process pr = new ProcessBuilder().inheritIO().command(cmd).redirectInput(Redirect.INHERIT).start();
PRlist.add(pr); commandsList.add(cmd);
}
}
catch (FileNotFoundException ex) {ex.printStackTrace();}
catch (IOException ex) {ex.printStackTrace();}
int streamnum = PRlist.size();
while (true){
for (int i = 0; i < streamnum; i++){
if (!PRlist.get(i).isAlive()){
PRlist.get(i).destroy();
PRlist.remove(i);
try {
Process PR = new ProcessBuilder().inheritIO().command(commandsList.get(i)).redirectInput(Redirect.INHERIT).start();
System.out.println(commandsList.get(i)[12] + " stream re-established at " + LocalDateTime.now().format(frmt));
PRlist.add(i,PR);
} catch (IOException ex) {ex.printStackTrace();}
}
}
try {
Thread.sleep(5000);
} catch (InterruptedException ex) {ex.printStackTrace();}
}
} else {
System.out.println("No stream file was specified.");
}
}}
如有任何帮助,我们将不胜感激。
也许你可以使用这些方法
**public ProcessBuilder.Redirect redirectError()**
Returns this process builder's standard error destination. Subprocesses subsequently started by this object's start() method redirect their standard error to this destination. The initial value is Redirect.PIPE.
Returns:
this process builder's standard error destination
或者
public abstract int exitValue()
Returns the exit value for the subprocess.
Returns:
the exit value of the subprocess represented by this Process object. By convention, the value 0 indicates normal termination.
Throws:
IllegalThreadStateException - if the subprocess represented by this Process object has not yet terminated
举个例子
有点像
if (!PRlist.get(i).isAlive()){
int exitCode=PRlist.get(i).exitValue();
//Do something with exitValue
PRlist.get(i).destroy();
PRlist.get(i).destroy();
PRlist.remove(i);
try {
Process PR = new ProcessBuilder().inheritIO().command(commandsList.get(i)).redirectInput(Redirect.INHERIT).start();
System.out.println(commandsList.get(i)[12] + " stream re-established at " + LocalDateTime.now().format(frmt));
PRlist.add(i,PR);
} catch (IOException ex) {ex.printStackTrace();}
}
带有 errorStream 的示例可能更复杂,但我们的想法是查看通过文本处理在 errorStream 中发布的异常。
好的,对于 Java 个线程,您可以这样做:
class MyThreadedApp {
// main() here
/**
* Starting a new thread
*/
private void start() {
new Thread(() -> {
try {
new Worker().run();
} catch (Exception ex) {
threadEnded(ex);
}
}).start();
}
/**
* Handle errors
*
* @param ex Error
*/
private void threadEnded(Exception ex) {
System.out.println(ex.getMessage());
}
}
/**
* My worker thread
*/
class Worker {
void run() throws IOException {
// Do my stuff here
}
}
这是一个基本示例,仅用于演示数据流。在实践中,您可以使用 @lscoughlin 提到的技术。
我有一个 class 作为 parent 进程。在其 运行 期间,它创建了许多 child 进程并同时 运行s 它们。每个 child 进程基本上都是一个连接到服务并从中提取数据的 HTTP 客户端。
目前,如果 child 进程之一因任何原因停止工作,parent 通过重新启动同一个 child 进程来处理 re-establishing 连接。
child 进程断开连接可能是由多种原因引起的。我想将 child 进程断开连接的原因传达给 parent 进程,并让 parent 进程根据断开连接的原因(套接字读取失败,404 未找到)采取相应行动, 401 未经授权等)。
可能吗? shortest/best 的方法是什么? 这是我的 Parent class:
public class Parent {
public static void main(String[] args){
List<Process> PRlist = new ArrayList<Process>();
List<String[]> commandsList = new ArrayList<String[]>();
DateTimeFormatter frmt = DateTimeFormatter.ofPattern("hh:mm:ss");
if (args.length == 2 && args[0].matches("-f")){
String dir = System.getProperty("user.dir");
String path = dir + "/" + args[1];
try {
FileReader fr = new FileReader(path);
BufferedReader bf = new BufferedReader(fr);
String line = "";
while ((line = bf.readLine()) != null){
String[] tk = line.split(" ");
String[] cmd = {"java", "-jar", "Child.jar", "-a", tk[0], "-p", tk[1],
"-u", tk[2], "-pw", tk[3], "-m", tk[4], "-s", tk[5]};
Process pr = new ProcessBuilder().inheritIO().command(cmd).redirectInput(Redirect.INHERIT).start();
PRlist.add(pr); commandsList.add(cmd);
}
}
catch (FileNotFoundException ex) {ex.printStackTrace();}
catch (IOException ex) {ex.printStackTrace();}
int streamnum = PRlist.size();
while (true){
for (int i = 0; i < streamnum; i++){
if (!PRlist.get(i).isAlive()){
PRlist.get(i).destroy();
PRlist.remove(i);
try {
Process PR = new ProcessBuilder().inheritIO().command(commandsList.get(i)).redirectInput(Redirect.INHERIT).start();
System.out.println(commandsList.get(i)[12] + " stream re-established at " + LocalDateTime.now().format(frmt));
PRlist.add(i,PR);
} catch (IOException ex) {ex.printStackTrace();}
}
}
try {
Thread.sleep(5000);
} catch (InterruptedException ex) {ex.printStackTrace();}
}
} else {
System.out.println("No stream file was specified.");
}
}}
如有任何帮助,我们将不胜感激。
也许你可以使用这些方法
**public ProcessBuilder.Redirect redirectError()**
Returns this process builder's standard error destination. Subprocesses subsequently started by this object's start() method redirect their standard error to this destination. The initial value is Redirect.PIPE.
Returns:
this process builder's standard error destination
或者
public abstract int exitValue()
Returns the exit value for the subprocess.
Returns:
the exit value of the subprocess represented by this Process object. By convention, the value 0 indicates normal termination.
Throws:
IllegalThreadStateException - if the subprocess represented by this Process object has not yet terminated
举个例子
有点像
if (!PRlist.get(i).isAlive()){
int exitCode=PRlist.get(i).exitValue();
//Do something with exitValue
PRlist.get(i).destroy();
PRlist.get(i).destroy();
PRlist.remove(i);
try {
Process PR = new ProcessBuilder().inheritIO().command(commandsList.get(i)).redirectInput(Redirect.INHERIT).start();
System.out.println(commandsList.get(i)[12] + " stream re-established at " + LocalDateTime.now().format(frmt));
PRlist.add(i,PR);
} catch (IOException ex) {ex.printStackTrace();}
}
带有 errorStream 的示例可能更复杂,但我们的想法是查看通过文本处理在 errorStream 中发布的异常。
好的,对于 Java 个线程,您可以这样做:
class MyThreadedApp {
// main() here
/**
* Starting a new thread
*/
private void start() {
new Thread(() -> {
try {
new Worker().run();
} catch (Exception ex) {
threadEnded(ex);
}
}).start();
}
/**
* Handle errors
*
* @param ex Error
*/
private void threadEnded(Exception ex) {
System.out.println(ex.getMessage());
}
}
/**
* My worker thread
*/
class Worker {
void run() throws IOException {
// Do my stuff here
}
}
这是一个基本示例,仅用于演示数据流。在实践中,您可以使用 @lscoughlin 提到的技术。