闲置的线程=坏?

ᴇʟᴇ*_*ᴀтᴇ 11 java multithreading asynchronous nio c10k

我想在一小组机器上支持大约10,000个并发HTTP客户端(尽可能小).我想在用户使用应用程序时保持与每个客户端的连接,以允许服务器推送更新.

我相信通常建议将async IO用于这些长期连接,以避免大量线程处于空闲状态.但线程闲置有什么问题?我发现线程模型在精神上更容易使用,但我不想做一些会让我头疼的事情.我想我将不得不进行实验,但我想知道是否有人知道以前的这些实验中的任何实验?

Mar*_*nik 5

异步 I/O 基本上意味着您的应用程序执行大部分线程调度。您不必让操作系统随机挂起您的线程并调度另一个线程,而是只拥有与 CPU 核心数量相同的线程,并在最合适的点让出其他任务(当线程到达 I/O 操作时,这将需要一些时间)。时间。

从性能的角度来看,上述似乎是一个明显的胜利,但异步编程模型在几个方面要复杂得多:

  1. 不能表示为单个函数调用,工作流程不明显,特别是考虑到异常导致的控制流转移;
  2. 如果没有编程语言专门有针对性的支持,习惯用法就会非常混乱:意大利面条式代码和/或极弱的信噪比是常态;
  3. 主要是由于 1. 上述调试要困难得多,因为堆栈跟踪并不代表整个工作单元内的进度;
  4. 执行在一个池(甚至是多个池,其中每个抽象层都有自己的池)内从一个线程跳转到另一个线程,因此使用常用工具进行分析和监视几乎毫无用处。

另一方面,现代操作系统发生了许多有利的改进和优化,大部分消除了同步 I/O 编程的性能缺点:

  • 地址空间很大,所以为堆栈保留的空间不是问题;
  • 调用堆栈的实际物理 RAM 负载不是很大,因为只有线程实际使用的堆栈部分才会提交给 RAM,并且调用堆栈通常不会超过 64K;
  • 上下文切换过去对于较大的线程数来说非常昂贵,现在已经改进到对于所有实际目的来说其开销可以忽略不计。

一篇讨论了上述大部分内容和其他一些观点的经典论文是对我在这里所说的内容的一个很好的补充:

https://www.usenix.org/legacy/events/hotos03/tech/full_papers/vonbehren/vonbehren_html/index.html