Serious problem with multithreaded I/O on Linux
Bryce McKinlay
bryce@albatross.co.nz
Wed Jul 14 18:28:00 GMT 1999
I posted this to the bug database yesterday (PR# 13), but I'm going to
repost it here just to make sure that I've got everyone's attention!
On Linux (using Redhat 6.0/glibc 2.1.1-6), Calling a blocking I/O method
[eg: anything that eventually calls FileDescriptor.read()] causes many
calls from all other threads to block also. This makes multithreaded I/O
(ie: reading from two sockets simultaneously) completely
unreliable/impossible. Other things, like starting a new thread, do not
work while the read() method is blocking.
At a guess, the problem has something to do with the way in which gcj is
interacting with LinuxThreads. Replacing the calls to read(), etc, in
java/io/natFileDescriptorPosix.cc with calls to __read(), etc, seems to
fix the problem - but I'm guessing that this forces the non-thread-aware
version of the function to be used, which is not what we want to do.
The following code demonstrates the problem. If things are working
right, it should print "this is okay" and exit. If not, it
will just hang until a key is pressed because the second thread does not
get created until the first unblocks:
import java.io.*;
public class BlockThread implements Runnable
{
private InputStream is;
public static void main(String args[])
{
try
{
BlockThread t = new BlockThread( System.in );
// give the BlockThread lots of time to start up
Thread.sleep(100);
BlockThread t2 = new BlockThread( null );
}
catch (Exception x) {};
}
public BlockThread (InputStream is)
{
// create a thread that blocks on reading the given input stream
this.is = is;
Thread t = new Thread(this);
t.start();
}
public void run()
{
if (is == null)
{
System.out.println("This is okay. Exiting.");
System.exit(0);
}
try
{
InputStreamReader isr = new InputStreamReader(is);
PrintWriter out = new PrintWriter(System.out);
char[] buffer = new char[100];
while (true)
{
System.out.println(this + " is about to block");
int len = isr.read(buffer, 0, buffer.length);
System.out.println(this + " has unblocked");
if (len < 0)
break;
out.write(buffer, 0, len);
}
}
catch (Exception x) {}
}
}
regards
[ bryce ]
More information about the Java
mailing list