Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Efficiency of while(true) ServerSocket Listen

I am wondering if a typical while(true) ServerSocket listen loop takes an entire core to wait and accept a client connection (Even when implementing runnable and using Thread .start())

I am implementing a type of distributed computing cluster and each computer needs every core it has for computation. A Master node needs to communicate with these computers (invoking static methods that modify the algorithm's functioning).

The reason I need to use sockets is due to the cross platform / cross language capabilities. In some cases, PHP will be invoking these java static methods.

I used a java profiler (YourKit) and I can see my running ServerSocket listen thread and it never sleeps and it's always running. Is there a better approach to do what I want? Or, will the performance hit be negligible?

Please, feel free to offer any suggestion if you can think of a better way (I've tried RMI, but it isn't supported cross-language.

Thanks everyone

like image 819
Submerged Avatar asked May 17 '10 20:05

Submerged


2 Answers

If you mean something like this:

while (true) {
  Socket socket = server.accept();
  /* Do something with socket... */
}

then, no, the call to accept() does not "take an entire core." It's a blocking call that will allow the CPU to be scheduled for another thread until a client actually connects. Once the call to accept() returns, the current thread will be scheduled to run and will consume CPU until it blocks on accept() in the next iteration of the loop.

To avoid the listen backlog of other clients growing too large, another thread usually handles interaction with the newly-accepted Socket, leaving one thread to focus on accepting new clients. The socket handling thread might handle many sockets, using NIO, or it might be dedicated to a single socket, which is much simpler to code but won't scale well past many hundreds of simultaneous connections.

like image 95
erickson Avatar answered Oct 27 '22 00:10

erickson


You might want to take a look at the Java 1.4 nio libraries and in particular ServerSocketChannel. I use this very successfully to implement an efficient server, the key bits of code are:

Selector selector = Selector.open();

ServerSocketChannel server= ServerSocketChannel.open();
server.socket().bind(new java.net.InetSocketAddress(port));
server.configureBlocking(false);
SelectionKey serverKey = server.register(selector, SelectionKey.OP_ACCEPT);

// start listening thread
new Thread(listener).start();

And the listener is just a loop that runs:

selector.select(1000); // listen for one second max
Set<SelectionKey> keys = selector.selectedKeys();

if (keys.size()>0) {
    handleKeys(keys);
}
like image 24
mikera Avatar answered Oct 26 '22 23:10

mikera