【问题标题】:How does Java NIO's selector check for available events under the hood?Java NIO 的选择器如何在后台检查可用事件?
【发布时间】:2015-07-10 07:29:19
【问题描述】:

before 有人问过类似的问题,但我想再提出一次,希望有人能帮助解决一些问题。作为一个实验,我尝试在不使用 NIO 的情况下用 Java 编写一个简单的“非阻塞”服务器,其中基本上需要三个线程:

  1. 主服务器线程 - accept()s 新套接字连接,并将每个新套接字放入队列中
  2. 读取工作线程-遍历队列中的每个套接字,并从每个套接字的输入流中读取一点点,并将其存储在InputQueue
  3. 编写工作线程 - 根据传入请求从每个套接字读取的时间,该工作线程将遍历所有需要响应的套接字,并再次在每次接收时写入几个字节的响应。

在上一个问题中指出,Java NIO 的select() 机制远比在每个socket 上轮询,并且在每次通过队列后休眠一点。我知道 select 理论上是如何工作的,但我难以理解的主要内容是:如果轮询不好且效率低下,select() 是如何在幕后做到的?

更新:我找到了this page,它更清楚地说明了原生select() 是如何工作的。有趣的是,确实,我最初的猜测似乎是正确的:select() 以线性方式工作,探测每个请求的文件描述符,类似于轮询机制所做的:

他们都 [select()poll()] 在一个 线性方式。您要求他们检查的描述符越多,速度就越慢 他们得到。一旦超过一百个文件描述符 左右 - 当然取决于你的 CPU 和硬件 - 你会开始 注意到仅仅等待文件描述符活动和 在检查它是哪个文件描述符之后,需要一个 重要的时间并成为瓶颈。

【问题讨论】:

  • 首先问自己一个问题:非阻塞是否值得麻烦?在绝大多数情况下,这不是...
  • 我知道,我的示例目前完全用于学习和说明目的。
  • 链接质量差。未经证实的猜测。不要相信您在互联网上阅读的所有内容。

标签: java multithreading sockets nio


【解决方案1】:

它调用操作系统中的select()方法,它:

  • 如果套接字接收缓冲区中有数据或 FIN,则认为套接字可读
  • 如果套接字发送缓冲区中有空间(即大部分时间),则认为套接字是可写的。

【讨论】:

  • 我理解这些,但我的问题是,即使在操作系统级别,它也必须进行某种分时和轮询,对吧?想象一下,如果有 10 个打开的套接字。我想象 select 所做的几乎与我在天真的非阻塞服务器中的代码所做的相同,但级别要低得多。我说的对吗?
  • 不,它会在内部阻塞,直到其中一个条件变为真或超时到期。当您在应用程序代码中遍历 FD_SET 时,会出现唯一的线性行为。无论您的链接声称如何,它都不是内部运作的方式。
  • 你有更好的资源吗?我真的非常有兴趣了解它是如何工作的。也许,我会去拿这本书:amazon.com/exec/obidos/ASIN/013490012X
  • W.R.史蒂文斯,TCP/IP 图解, 第二卷。
猜你喜欢
  • 2015-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多