调用Process.waitfor导致的进程挂起

问题背景

如果要在Java中调用shell脚本时,可以使用Runtime.exec或ProcessBuilder.start。它们都会返回一个Process对象,通过这个Process可以对获取脚本执行的输出,然后在Java中进行相应处理。例如,下面的代码:

		try 
		{
			Process process = Runtime.getRuntime().exec(cmd);
			
			process.waitFor();
                        
                        //do something ...
		} 
		catch (Exception e) 
		{			
			e.printStackTrace();
		}

通常,安全编码规范中都会指出:使用Process.waitfor的时候,可能导致进程阻塞,甚至死锁。 那么这句应该怎么理解呢?用个实际的例子说明下。

问题描述

         使用Java代码调用shell脚本,执行后会发现Java进程和Shell进程都会挂起,无法结束。

Java代码 processtest.java

		try 
		{
			Process process = Runtime.getRuntime().exec(cmd);
			System.out.println("start run cmd=" + cmd);
			
			process.waitFor();
			System.out.println("finish run cmd=" + cmd);
		} 
		catch (Exception e) 
		{			
			e.printStackTrace();
		}

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值