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

时间:2013-03-07 17:00:33

标签: c# .net multithreading threadpool manualresetevent

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

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

因此,这个线程池可以创建数千个线程,但是当其他任务完成时,MRE上的所有线程都会被阻止(或者你配置的任何线程)。

我的问题:


对内存/处理器的影响是否会阻塞MRE上的一千个线程?我没有太多时间来修复这个峰值,所以如果它是最小的,我宁愿留下问题,并在我有更多时间时在稍后的补丁中修复它。

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

1 个答案:

答案 0 :(得分:3)

  

对内存/处理器的影响是否会阻塞MRE上的一千个线程?我没有太多时间来修复这个峰值,所以如果它是最小的,我宁愿留下问题,并在我有更多时间时在稍后的补丁中修复它。

每个线程在手动创建时都会分配给它自己的堆栈。默认情况下,每个线程为1MB,但可以make threads with a smaller stack via a constructor parameter

从问题描述到使用标准ThreadPool以及像BlockingCollection<T>这样的类来处理你的限制,你会更好地重新设计它。这是为了直接允许带有阻塞的边界输入。制作无限数量线程的自定义“线程池”的效率远远低于使用框架中包含的高度调整的ThreadPool。

  

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

这绝对是有缺陷的。 ThreadPool的整个要点是避免为每个请求创建一个线程,并为多个请求“池化”线程(重用它们),而不必重新创建它们。