Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple selectors in multiple threads

Is it beneficial to distribute incoming connections among n threads, each with its own independent NIO Selector, where n is, say, the number of cores in the server? Suppose I'm writing a server, which should handle a number of client connections. I could have something like:

selector.select();
Iterator<SelectionKey> i = selector.selectedKeys().iterator();

while (i.hasNext()) {
   SelectionKey key = i.next();
   i.remove();

   if (!key.isValid())
      continue;

   if (key.isAcceptable()) {
      // get one of the n selectors (I'd have one per core)
      Selector chosenSelector = getRandomSelector();

      // delegate the new connection to the chosen selector
      SocketChannel newChannel = key.channel.accept();
      newChannel.configureBlocking(false);
      newChannel.register(chosenSelector, SelectionKey.OP_READ);
   }
}

Do you guys think this makes sense? I mean, running n threads, each with a different selector? Or should I just stick to having one single selector thread that handles OP_READ for all connections? Or maybe something else?

like image 795
Eduardo Bezerra Avatar asked Mar 03 '14 13:03

Eduardo Bezerra


People also ask

What will happen if multiple threads accessing the same resource?

Multiple threads accessing shared data simultaneously may lead to a timing dependent error known as data race condition. Data races may be hidden in the code without interfering or harming the program execution until the moment when threads are scheduled in a scenario (the condition) that break the program execution.

Can multiple threads exist on one?

Many threads can run in a single process and each thread must be part of a process as it cannot exist on its own.

What is a selector thread?

A selector provides a mechanism for monitoring one or more NIO channels and recognizing when one or more become available for data transfer. This way, a single thread can be used for managing multiple channels, and thus multiple network connections.

How selector works in java?

select. Selects a set of keys whose corresponding channels are ready for I/O operations. This method performs a blocking selection operation. It returns only after at least one channel is selected, this selector's wakeup method is invoked, or the current thread is interrupted, whichever comes first.


2 Answers

No it is not beneficial, as the relation of code that needs to be processed vs. the time it takes for the IO operations is negligible. Especially if you consider the extra time you would need for the synchronization of fragmented data. It is however beneficial to have the processing of the received data done in separate threads.

So basically: have a single-threaded selector loop that copies the data from one buffer into a task-buffer for further processing in a separate thread, then launch a Runnable with that task-buffer in an Executor to process that copied data.

like image 185
TwoThe Avatar answered Oct 24 '22 09:10

TwoThe


This is exactly what Netty does. It uses N threads calling Selector.select() where N = (num available CPUs * 2) It is multiplied by 2 because of hyperthreading. This is the parent EventLoop which is considered the "acceptor eventloop" for accepting socket connections. Then there is the child EventLoop of thread workers

Suggest you have a look at NioEventLoopGroup-class

like image 23
Ciccio Avatar answered Oct 24 '22 10:10

Ciccio