JAVA process hang when expectts error stream from C++ application

K

krishnamurthi.g

Hi friends,

My JAVA program has to call c++ (kkk) application and JAVA opens 2
threads to read outputstream and errorstream from c++ application.
See the code below). Since errorstream is expecting some data it hangs
unless c++ feeds the same.
When I used alternative 'perror("")'/'perror(NULL)' in kkk.c hang gets
solved but c++ standalone program keeps throwing dummy error on
screen.
Could anybody help me here how it can be rectified.
Thanks in advance
- Krish


------------
start.java:
-----------
public class start
{
public static void main(String [] args) throws
IOException,InterruptedException
{
String cmd = "/home/user/kkk";
Process process = Runtime.getRuntime().exec(cmd);
MyReader outReader = new MyReader(process.getInputStream());
Thread outThread = new Thread(outReader);
outThread.start();
MyReader errReader = new MyReader(process.getErrorStream());
Thread errThread = new Thread(errReader);
errThread.start();
System.out.println("exit code is " + process.waitFor());
//process.destroy();
// process.getInputStream().close();
// process.getErrorStream().close();
outThread.join();
errThread.join();
System.out.println("joins completed");
}
}

/***** MyReader.java *******/

import java.io.*;
public class MyReader implements Runnable
{
private final InputStream is;
public MyReader(InputStream is)
{
this.is = is;
}
public void run()
{
// normally would read in while here, but these threads never get
any
// they are blocked on the first read() call forever.
int length;
try
{
length = is.read();
if (length == -1)
{
System.out.println("-1");
return;
}
if (length == 0)
{
System.out.println("0");
return;
}
System.out.println("read something");
} catch (Throwable t) {
System.out.println(t);
}
}
}


kkk.c:
-------
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
# include <sys/wait.h>

int main()
{
perror ("");
// perror (NULL);
return 0;
}
 
G

Gordon Beaton

My JAVA program has to call c++ (kkk) application and JAVA opens 2
threads to read outputstream and errorstream from c++ application.
See the code below). Since errorstream is expecting some data it
hangs unless c++ feeds the same.

I don't understand how this is a problem - it will only "hang" while
the child process is still running. But when the child exits, EOF will
be indicated by is.read() allowing the reader thread to exit too.

If you know in advance that the child will *never* write to stderr,
close it in the c++ program. That too will cause EOF to be indicated
by in.read(), and the reader thread can exit.

/gordon

--
 
K

krishnamurthi.g

I don't understand how this is a problem - it will only "hang" while
the child process is still running. But when the child exits, EOF will
be indicated by is.read() allowing the reader thread to exit too.

If you know in advance that the child will *never* write to stderr,
close it in the c++ program. That too will cause EOF to be indicated
by in.read(), and the reader thread can exit.

/gordon

--

======
Dear Gordon,

Thanks for your quick response.
Sorry that I forgot to mention one more thing.
The kkk c++ exe calls myfork c++ exe which simply forks and keeps
child in loop and parent gets exited.
In this scenario, kkk too gets exited and myfork is running in loop
and JAVA application hangs if there
is no perror() in kkk. If perror() is inserted JAVA won't hang at all.
So independantly running kkk will throw

# kkk
I am child 23520
I am Parent 23519
Invalid argument <----- error message
#

Thanks
- Krish

kkk.c:
-------
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
# include <sys/wait.h>

int main()
{
system("/home/user/myfork");
perror ("");
// perror (NULL);
return 0;
}

myfork.c:
--------
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
# include <sys/wait.h>
int main()
{
switch(fork())
{
case 0:
printf("\nI am child %d", getpid());
break;
case -1:
printf("\nError");
break;
default :
printf("\nI am Parent %d", getpid());
exit(0);
}
while(1)
{
}
}
 
G

Gordon Beaton

Sorry that I forgot to mention one more thing. The kkk c++ exe calls
myfork c++ exe which simply forks and keeps child in loop and parent
gets exited.

Don't waste people's time by posting half the problem. The fork() is
extremely significant to the issue.
In this scenario, kkk too gets exited and myfork is running in loop
and JAVA application hangs if there is no perror() in kkk. If
perror() is inserted JAVA won't hang at all.

It isn't apparent what you are trying to achieve by creating this tree
of processes.

Every time you fork(), both parent and child processes share the same
set of descriptors. Your use of system() complicates the picture
somewhat, since it also creates a shell in addition to the "real"
child process. And all of these processes share the same set of
descriptors.

Here is one simple rule: as long as any process still holds an open
stderr descriptor, the reader thread will continue to block on read.
EOF will be reached only when there are *no* remaining processes
holding the descriptor.

It isn't necessary to write nonsense messages to stderr to make this
work, but you need to keep proper track of your processes and
descriptors, closing any unused ones as you go, or making sure that
all of your processes exit properly.

/gordon

--
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,185
Members
46,736
Latest member
AdolphBig6

Latest Threads

Top