1、前言:
最近在做一个需求需要调用linux下的某个脚本来对ai的模型进行训练,很简单的需求,我像往常一样写下如下的代码片段:
Process process = Runtime.getRuntime().exec(cmd);
process.waitFor();
But当我运行代码时,发现代码执行到waitFor后阻塞住了,我以为这也许是训练模型需要时间,毕竟是同步阻塞的方法,那我就等一会吧!
一分钟……两分钟……10分钟……
我渐渐的意识到,这TM不对劲啊!
于是我通过以下命令查询了下linux执行情况。
ps aux |grep xxx.sh
输出的结果显示该脚本当前还在运行,而脚本的日志并没有从inputstream进行输出。我渐渐的慌了!
2 问题分析
2.1 观看JDK文档
根据查看JDK的文档,我看到Process.waitFor可能导致死锁?!仔细观看JDK的文档说明,发现文档上已经对死锁的情况进行了分析。
如果InputStream使用的buffer缓冲区有限的话,可能会导致阻塞和死锁 。
2.2 死锁原因
经过查阅资料,发现
- 当我们使用Runtime.exec执行命令时,JAVA的线程会创建一个子进程,用于执行命令,而且子进程和JAVA线程会分别独立运行。
- JAVA线程需要等待命令的执行完成,对命令的日志和返回值进行处理,所以我们在JAVA线程中调用Process.waitFor挂起来等待子进程完成。
- 子进程执行时,不断的打印日志信息,我们通过Process.g