尝试从子进程stdout读取时程序挂起

时间:2012-12-10 20:35:32

标签: java process io

我等待启动进程,向其传递一个整数,并获取一个打印出来的值。我尝试了以下(在Windows中):

public class Example {

    public static Boolean call() throws IOException {
        String mFilename = "f.exe";
        int mParam = 0;
        Process p = Runtime.getRuntime().exec(mFilename);
        BufferedReader input = new BufferedReader
                (new InputStreamReader(p.getInputStream()));
        BufferedWriter output = new BufferedWriter
                (new OutputStreamWriter(p.getOutputStream()));
        output.write(mParam);
        output.flush();
        char retVal = (char) input.read();
        return !(retVal == '0');
    }

    public static void main(String[] args) throws IOException {
        System.out.println(call());
    }
}

mFilename是可执行文件的路径。如果mParam为0,则进程返回1表示正输入,0表示负数,并保持无限循环。但是,我发现无论我传递给它的值是什么,retVal始终为1我做错了什么?

请原谅我在几分钟之前删除了这个问题,我认为问题发生在retVal,但显然这不是此代码中的唯一问题。

子进程,用C ++编写:

#include <iostream>
#include <Windows.h>

bool f(int x)
{
    if (x)
        return x > 0;

    while (1)
        Sleep(100);
}

int main()
{
    int x;
    std::cin>>x;
    std::cout<<f(x);
}

更新

我发现了至少一个错误。由于mParam是一个整数,由一个可选符号和一串数字组成,output.write写入字符,我需要将整数写为字符数组:

char[] arr = String.valueOf(mParam).toCharArray();
output.write(arr);

但是,无论输入如何,在此修复程序挂起后

char retVal = (char) input.read();

1 个答案:

答案 0 :(得分:0)

嗯,解决方案结果非常简单:std::cin只是想要一个新行来成功读取整数。结果代码如下:

public Boolean call() throws IOException, InterruptedException, ExecutionException, TimeoutException {
    Process p = Runtime.getRuntime().exec(mFilename);
    final BufferedReader input = new BufferedReader
            (new InputStreamReader(p.getInputStream()));
    final BufferedWriter output = new BufferedWriter
            (new OutputStreamWriter(p.getOutputStream()));
    output.write(Integer.toString(mParam));
    output.newLine();
    output.flush();

    ExecutorService executor = Executors.newFixedThreadPool(2);
    Callable<Character> readTask = new Callable<Character>() {
        @Override
        public Character call() throws Exception {
            return Character.valueOf((char)input.read());
        }
    };
    Future<Character> future = executor.submit(readTask);
    char readVal;
    try {
        readVal = future.get(3L, TimeUnit.SECONDS);
    } finally {
        p.destroy();
        executor.shutdownNow();
    }

    return !(readVal == '0');
}

请注意,我添加了对“无限循环”情况的支持。如果我们无法在3秒内从stdout获取输出,则抛出异常并终止子进程。我不在这里处理异常因为函数必须返回一些结果,但是在无限循环的情况下我没有任何结果返回。