Process.waifor()导致调用的进程异常挂起问题

实在是这个月该类问题比较突出了,几乎是每个星期都出现同样的问题,资源在下载到执行机器后,进行操作的线程突然就没了,但是在前端显示这个进程还在运行着,这就导致卡死了,(用户已经等待了几个小时了)。

这问题已经定位到了具体的位置了,就几行代码,

class ProcessUtil{
    public void executor(){
        String file = "......";
        Pressess process = null;
        try{
            process = Runtime.getRuntime().exec(file);
        }
        catch(Throwable e){
            logger.err();
        }finally{
            waitfor();
        }
    }
}

每次都发生在资源部署结束后,(下载资源包,马上开始调用解压,执行等命令的时候)

我这种菜鸟怎么可能独立找到问题所在呢,只有谷歌才能救我了。。。。

原因就是这些:
1. 主进程中调用Runtime.exec会创建一个子进程,用于执行脚本。子进程创建后会和主进程分别独立运行。
2. 因为主进程需要等待脚本执行完成,然后对脚本返回值或输出进行处理,所以这里主进程调用Process.waitfor等待子进程完成。
3. 通过shell脚本可以看出:子进程执行过程就是不断的打印信息。主进程中可以通过Process.getInputStream和Process.getErrorStream获取并处理。
4. 这时候子进程不断向主进程发生数据,而主进程调用Process.waitfor后已挂起。当前子进程和主进程之间的缓冲区塞满后,子进程不能继续写数据,然后也会挂起。
5. 这样子进程等待主进程读取数据,主进程等待子进程结束,两个进程相互等待,最终导致死锁。

嘿嘿————

其实就是一个原因:空间满了。

查了好几个地方的解决方法:基本上都是开线程,单独开启两个额外的线程,分别处理InputStream和ErrorStream就可以了。

代码就不写了,没发现有什么区别,都一样。

最关键的是,因为历史原因,产品的执行环境实在win7环境运行的,然后安装了cygwin64后模拟出的linux环境,所以实际上是window下的java环境。检查环境是一个非常费劲的事。
坑——

参考:
https://blog.csdn.net/seapeak007/article/details/69668600

猜你喜欢

转载自blog.csdn.net/u010887126/article/details/80740723