繁体   English   中英

闲置的线程=坏?

[英]Threads sitting idle = bad?

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

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

异步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

您的问题的评论中已经有一些很好的指示。

不使用10K线程的原因是这会花费内存资源,而内存会耗费能量。 编程模型没有参数,因为坐在客户端连接上的线程不能与想要发布事件的线程相同。

请查看Servlet 3.0标准中的websockets标准和异步请求处理模型。 所有最近的Java Web应用程序服务器现在都实现它(例如Glassfish和Tomcat),它是您的问题的解决方案。

由于您使用的操作系统,JVM和应用程序服务器缺失,因此无法回答问题本身。 但是,您可以通过使用Thread.sleep(9999999)创建一个servlet或JSP并在其上执行siege -c 10000 ...来快速测试它。

10,000个同时发生的HTTP客户端......让线程空闲的问题是什么?

似乎空闲线程的成本只是为内核结构(几kb)和线程堆栈(512kb-一个mb的数量)分配的内存。 但...

显然,你会不时地唤醒你的每一百个线程,对吧? 这是您支付上下文切换成本的时刻,这可能不是那么小(调用系统调度程序的时间,更多的缓存未命中等)。 例如,见: http//www.cs.rochester.edu/u/cli/research/switch.pdf

而且你必须非常小心地固定你的线程,以免影响系统线程。 因此,与异步IO相比,每次连接线程(在阻塞IO上)架构可能会增加系统的延迟。 但是,如果几乎所有线程都停在大部分时间,它仍然适用于您的情况。

最后一句话。 我们不知道你的线程将在read()上被阻塞多少次,以及他们需要做多少工作来处理接收到的数据。 将使用哪些硬件,操作系统和网络接口......因此,测试系统的原型。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM