【问题标题】:What resources do blocked threads take-up阻塞线程占用什么资源
【发布时间】:2010-11-04 16:27:57
【问题描述】:

在异步编程模型中编写代码(更具体地说 - 使用回调而不是阻塞线程)的主要目的之一是尽量减少系统中阻塞线程的数量。

对于运行线程,这个目标是显而易见的,因为上下文切换和同步成本。

但是阻塞的线程呢?为什么减少他们的数量如此重要?

例如,当等待来自网络服务器的响应时,线程被阻塞,不占用任何 CPU 时间,也不参与任何上下文切换。

所以我的问题是: 除了 RAM(每个线程大约 1MB?)阻塞的线程还占用了哪些其他资源?

还有一个更主观的问题: 在什么情况下,这样的成本才能真正证明编写异步代码的麻烦是合理的(例如,代价可能是将你好的连贯方法拆分为许多 beginXXX 和 EndXXX 方法,并将参数和局部变量移动为类字段)。

更新 - 我没有提及或没有给予足够重视的其他原因:

  1. 更多线程意味着更多地锁定公共资源

  2. 更多的线程意味着更多的线程创建和处理,这是昂贵的

  3. 系统肯定会耗尽线程/RAM,然后停止为客户端提供服务(在 Web 服务器场景中,这实际上会导致服务中断)

【问题讨论】:

  • Quib​​ble:答案可能取决于上下文。例如,IIS 工作线程是一种有限的商品,而操作系统线程则不那么重要。细节会很有帮助。
  • 我从来没有听说过最小化现有线程的数量是异步代码的目的。根据定义,异步代码依赖于比同步(单线程!)代码更多的线程。
  • @Harper: Disagree.
  • 顺便说一下,IIS 线程默认只有 256Kb 的堆栈,而不是默认的 1Meg。
  • @Craig Stuntz:我的主要观点是,限制使用的线程数并不是使用异步方法的原因

标签: c# .net multithreading asynchronous


【解决方案1】:

所以我的问题是:除了 RAM(每个线程大约 1MB?)阻塞的线程还占用了哪些其他资源?

这是最大的之一。话虽如此,.NET 中的 ThreadPool 允许每个核心有这么多线程是有原因的 - 在 3.5 the default was 250 worker threads per core in the system 中。 (在 .NET 4 中,它取决于系统信息,例如虚拟地址大小、平台等 - 现在没有固定的默认值。)线程,尤其是阻塞线程,真的没有那么昂贵......

但是,我想说,从代码管理的角度来看,减少阻塞线程的数量是值得的。每个被阻塞的线程都是一个操作,在某个时候应该返回并被解除阻塞。拥有其中许多意味着您需要管理一组相当复杂的代码。减少这个数字将有助于保持代码库更简单 - 并且更易于维护。

还有一个更主观的问题:在什么情况下,这样的成本才真正证明编写异步代码的麻烦是合理的(例如,代价可能是将你好的连贯方法拆分为许多 beginXXX 和 EndXXX 方法,以及移动参数和本地变量是类字段)。

现在,这通常是一种痛苦。这在很大程度上取决于场景。然而,.NET 4 中的Task<T> 类在许多情况下都极大地改进了这一点。使用 TPL 比以前使用 APM (BeginXXX/EndXXX) 甚至 EAP 的痛苦要小得多。

这就是语言设计者在improving this situation in the future 上投入如此多精力的原因。他们的目标是让异步代码更易于编写,以便更频繁地使用它。

【讨论】:

    【解决方案2】:

    除了被阻塞的线程可能持有锁的任何资源之外,线程池的大小也是一个考虑因素。如果您已达到最大线程池大小(如果我没记错的话,.NET 4 的最大线程数是每个 CPU 100 个)您根本无法在线程池上运行其他任何东西,直到至少有一个线程获得解放了。

    【讨论】:

    【解决方案3】:

    我想指出,堆栈内存的 1MB 数字(或 256KB,或任何设置的值)是预留空间;虽然它确实占用了可用地址空间,但实际内存仅在需要时提交。

    另一方面,拥有大量线程势必会使任务调度程序在某种程度上陷入困境,因为它必须跟踪它们(自上次滴答以来已变得可运行,依此类推)。

    【讨论】:

    • 托管代码中并非如此,CLR 提交整个堆栈。有一篇 Chris Brumme 的博客文章记录了这一点。 Joe Duffy 也写过博客。寻找,你们就会找到。
    • 我没有意识到这一点。这是蹩脚的,恕我直言。
    猜你喜欢
    • 1970-01-01
    • 2012-06-13
    • 2021-10-19
    • 2020-08-06
    • 1970-01-01
    • 2021-08-29
    • 2021-11-12
    • 2020-01-02
    相关资源
    最近更新 更多