PRB: Process.waitFor() Enters a Deadlock When Parent Process Does Not Read Child Process Data (326709)



The information in this article applies to:

  • Microsoft Visual J# .NET (2002)
  • Microsoft Visual J# .NET (2003)

This article was previously published under Q326709

SYMPTOMS

Process.waitFor() appears to enter a deadlock when the child process writes a lot of data to its output stream and the parent process never reads the data.

CAUSE

The Runtime.exec() method creates a pipe for the standard output. When the child process writes a large amount of data to this pipe so that the buffer is full, it blocks on the pipe until the data in the pipe buffer is read by the parent process. If the parent process never reads the standard output, Process.waitFor() does not return.

RESOLUTION

To prevent blocking, make sure that the parent process always reads the standard output from the child process.

STATUS

This behavior is by design.

MORE INFORMATION

The following sample program starts a child process, WriteALot.exe, and then waits for it to return. Note that code has been added to read the output from WriteALot.exe so that Process.waitFor() does not deadlock.
import java.io.*;

public class Class1
{
	public static void main(String[] args)
	{
		String command = "WriteALot.exe";
		try 
		{
			Process pr = Runtime.getRuntime().exec(command);
			System.out.print("Waiting...");
			new PrintStream(pr.getInputStream()).start();
			pr.waitFor();
			System.out.println("Done!");
			int exitValue = pr.exitValue();
			System.out.println("The exit value is " + exitValue);
		} 
		catch (Throwable t) 
		{
			System.out.println("Caught " + t);
		}
	}
}

class PrintStream extends Thread 
{
	java.io.InputStream __is = null;
	public PrintStream(java.io.InputStream is) 
	{
		__is = is;
	} 

	public void run() 
	{
		try 
		{
			while(this != null) 
			{
				int _ch = __is.read();
				if(_ch != -1) 
					System.out.print((char)_ch); 
				else break;
			}
		} 
		catch (Exception e) 
		{
			e.printStackTrace();
		} 
	}
}
				
The following is code for WriteALot, a Microsoft Visual C++ .NET console application:
//WriteALot.cpp
#include "stdafx.h"
#include "stdio.h"

int _tmain(int argc, _TCHAR* argv[])
{
	for (int i=0; i<1000; i++)
	{
		printf("Writing %dth record\n", i);
	}
	return 0;
}
				

Modification Type:MajorLast Reviewed:8/7/2003
Keywords:kbStreaming kbprb KB326709