多个线程中的多个选择器

问题描述 投票:8回答:3

在n个线程之间分配传入连接是否有益,每个线程都有自己独立的NIO Selector,其中n是服务器中的核心数量?假设我正在编写一个服务器,它应该处理许多客户端连接。我可以有类似的东西:

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);
   }
}

你们认为这有道理吗?我的意思是,运行n个线程,每个线程都有不同的选择器?或者我应该坚持使用一个单一的选择器线程来处理所有连接的OP_READ?或者别的什么?

java multithreading selector nio
3个回答
3
投票

不,它没有益处,因为需要处理的代码与IO操作所花费的时间之间的关系可以忽略不计。特别是如果您考虑分段数据同步所需的额外时间。然而,在单独的线程中完成接收数据的处理是有益的。

所以基本上:有一个单线程选择器循环,它将数据从一个缓冲区复制到任务缓冲区,以便在单独的线程中进一步处理,然后在Executor中启动带有该任务缓冲区的Runnable来处理复制的数据。


0
投票

在n个线程之间分配传入连接是否有益,每个线程都有自己独立的NIO选择器,其中n是服务器中的核心数量?

所有主要框架都以这种方式运作; Mina,Netty,Nginx等都在多个选择器之间分配套接字。 Nginx字面上将文件描述符传递给具有自己的选择器的分叉进程。

你在这里描述的是基本的选择器 - 工人模型。每个核心通常有2名工人。每个工人都有一个Selector。这个模型在Windows上是绝对必要的,因为每个Selector只能处理1024个套接字,而JDK所做的解决方案对于性能来说是灾难性的。

http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b27/sun/nio/ch/WindowsSelectorImpl.java

  • 核心0 - 线程 - >选择器 - > OP_READ / OP_WRITE - >做业务逻辑
  • 核心1 - 线程 - >选择器 - > OP_READ / OP_WRITE - >做业务逻辑
  • 核心2 - 线程 - >选择器 - > OP_READ / OP_WRITE - >做业务逻辑
  • 核心3 - 线程 - >选择器 - > OP_READ / OP_WRITE - >做业务逻辑

这是缩放反应器模式的基本方法。

重要的是单个SocketChannel只附加到单个Selector。因此,不要将SocketChannel.register()调用到一堆Selectors并在所有这些上面听OP_READ因为你不会获得任何好处。

http://man7.org/linux/man-pages/man7/epoll.7.html

Q2两个epoll实例可以等待相同的文件描述符吗?如果是这样,是否向两个epoll文件描述符报告了事件?

A2是的,会向两者报告事件。但是,可能需要仔细编程才能正确执行此操作。


-1
投票

我只有一个选择器,让它通过无锁环缓冲区在固定数量的线程上分发消息。然后,您可以完全无锁,超快速地进行流动。流程将是这样的:

Critical Selector => DEMUX =>工作线程=> MUX =>临界选择器

您只需要确保您的工作线程数量足够(并且您有足够的可用内核)来快速处理您的消息,否则您最终可能会使用完整的DEMUX,并且选择器必须阻止或丢弃消息。

我建议你阅读this article,了解异步,单线程,非阻塞网络框架的工作原理。当然你也可以查看Netty或Mina。有关延迟的概念,您必须使用demux和mux(纳秒)来支付,请参阅this benchmark

© www.soinside.com 2019 - 2024. All rights reserved.