Eri*_* C. 5 java multithreading process
我编写了一个java类来执行多线程任务,每个任务都运行一个外部进程.该过程负责将".chp"文件转换为".txt"文件.它用C语写.
这个过程在某个时刻中断,因为当我在终端中查看"顶部"时它会消失(可能是由于chp文件损坏).问题是我的java线程中的进程没有返回."process.waitFor()"似乎永远持续下去(至少是我为ExecutorService指定的12小时).
我做错了什么(没有捕捉异常?)?我尝试在MyThread中设置一个String类型的类变量,并输入一个错误消息代替抛出一个新的RuntimeException,然后在main的末尾打印String,但是线程代码没有达到这一点.它仍然停留在waitFor().
一旦C程序失败,进程是否应该终止?
程序在终端上打印(cf:MyThread):
A
B
C
Run Code Online (Sandbox Code Playgroud)
主要:
String pathToBin = "/path/to/bin";
List<MyThread> threadList = new ArrayList<MyThread>();
for (File f : folderList) {
File[] chpFilesInFolder = f.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
if (name.endsWith(".chp")){
return true;
}else{
return false;
}
}
});
File chpFile = writeChpFiles(chpFilesInFolder);
String[] cmd = {pathToBin, "--arg1", chpFile, "--out-dir", outputFolder};
MyThread t = new MyThread(cmd, f, chpFilesInFolder);
threadList.add(t);
}
ExecutorService threadExecutor = Executors.newFixedThreadPool(4);
for(MyThread th : threadList){
threadExecutor.execute(th);
}
threadExecutor.shutdown();
try {
threadExecutor.awaitTermination(12, TimeUnit.HOURS);
} catch (InterruptedException e) {
e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)
MyThread的:
class MyThread extends Thread{
private String[] cmd;
private File chpFolder;
private File[] chpFilesInFolder;
public MyThread(String[] cmd, File chpFolder, File[] chpFilesInFolder){
this.cmd = cmd;
this.chpFolder = chpFolder;
this.chpFilesInFolder = chpFilesInFolder;
}
@Override
public void run() {
Process process = null;
try{
System.err.println("A ");
ProcessBuilder procBuilder = new ProcessBuilder(cmd);
procBuilder.redirectErrorStream(true);
System.err.println("B");
process = procBuilder.start();
System.err.println("C");
process.waitFor();
System.err.println("D");
if(process.exitValue()!=0) System.err.println("ERROR !"+process.exitValue());
System.err.println("E");
}catch(IOException e){
e.printStackTrace();
}catch(InterruptedException e){
e.printStackTrace();
}catch(Throwable e){
e.printStackTrace();
}finally{
System.err.println("F");
if(process!=null) {try { process.destroy();} catch(Exception err) {err.printStackTrace();}}
}
File[] txtFilesInFolder = chpFolder.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
if (name.endsWith(".chp.txt")){
return true;
}else{
return false;
}
}
});
if (txtFilesInFolder.length==chpFilesInFolder.length){
for (File chp : chpFilesInFolder) {
chp.delete();
}
File logFile = new File(chpFolder, "apt-chp-to-txt.log");
if (logFile.exists()){
logFile.delete();
}
}else{
throw new RuntimeException("CHPs have not all been transformed to TXT in "+chpFolder.getAbsolutePath());
}
Run Code Online (Sandbox Code Playgroud)
小智 3
您的 C 程序是否有可能在 stdout 上生成输出?如果是这样,您需要在 Process.waitFor() 返回之前读取 Process.getOutputStream() - 请参阅https://bugs.java.com/bugdatabase/view_bug?bug_id=4254231
或者,将您的 C 程序称为重定向 stdout 的 shell 脚本。
您可以使用 jstack 命令来确认线程确实被阻塞在 Process.waitFor() 处。