代码之家  ›  专栏  ›  技术社区  ›  John Humphreys

创建大量系统线程并等待MRE的影响?

  •  2
  • John Humphreys  · 技术社区  · 11 年前

    我正在尝试修复一个非常大的应用程序中的内存峰值。虽然我不确定这会对记忆力产生多大影响,但我注意到了以下几点:

    • 应用程序使用自定义线程池来执行所有昂贵的任务
    • 应用程序将执行所有传入任务
    • 任务可以由数千个子任务组成
    • 虽然线程池一次只执行{T}个任务,并且在启动新任务之前完全完成任务,但它确实会创建一个新的系统线程(线程类),并为添加到其中的每个子任务启动它
    • 子任务系统线程通过线程启动启动,该线程启动会立即阻止手动重置事件(MRE),等待线程池插槽释放

    因此,这个线程池可以创建数千个线程,但在其他任务完成时,MRE上除了30个(或您配置的任何线程)之外的所有线程都将被阻止。

    我的问题:


    一千个线程在MRE上被阻塞会对内存/处理器产生什么影响?我没有太多时间来修复这个峰值,所以如果它很小,我宁愿把这个问题放在一边,等我有更多时间的时候再打补丁修复它。

    此外,这种行为在线程池中是典型的吗,还是听起来有缺陷(我倾向于有缺陷,但我没有足够好的背景来确定)。

    1 回复  |  直到 11 年前
        1
  •  3
  •   Reed Copsey    11 年前

    一千个线程在MRE上被阻塞会对内存/处理器产生什么影响?我没有太多时间来修复这个峰值,所以如果它很小,我宁愿把这个问题放在一边,等我有更多时间的时候再打补丁修复它。

    当手动创建时,每个线程都有自己的堆栈分配给它。默认情况下,这将是每个线程1MB,尽管可以 make threads with a smaller stack via a constructor parameter .

    从对问题的描述来看,你最好重新设计它,使用标准的ThreadPool和类似的类 BlockingCollection<T> 以处理您的节流。这是为了直接允许边界输入,并带有块。制作一个由无限多个线程组成的自定义“线程池”的效率将远远低于使用框架中包含的经过高度调优的ThreadPool。

    此外,这种行为在线程池中是典型的吗,还是听起来有缺陷(我倾向于有缺陷,但我没有足够好的背景来确定)。

    这肯定是有缺陷的。ThreadPool的全部目的是避免为每个请求创建一个线程,并为多个请求“池化”线程(重用它们),而不必重新创建它们。