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

标签 c# .net multithreading threadpool manualresetevent

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

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

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

我的问题:


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

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

最佳答案

What impact on the memory/processor will a thousand threads blocked on MREs have? I don't have a lot of time to fix this spike, so if it's minimal, I'd rather leave the issue and work to fix it in a later patch when I have more time.

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

您最好根据问题的描述重新设计它,以使用标准 ThreadPool 和类似 BlockingCollection<T> 的类。来处理你的节流。其设计目的是直接允许边界输入,并进行阻塞。制作无限数量线程的自定义“线程池”将比使用框架中包含的高度调整的线程池效率低得多。

Also, is this behavior typical in thread pools, or does this sound flawed (I'm leaning towards flawed, but I don't have a good enough background to be sure).

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

关于c# - 创建大量系统线程并等待 MRE 的影响?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15277228/

相关文章:

c# - 在内循环中尝试使用 savechanges() 进行保存时出现事务错误

c# - 如何对 Enum 执行 LINQ 查询?

c# - NHibernate尝试为FK映射插入现有记录,但仅当int ID为0时

C++线程安全——读图

c++ - 为什么单个线程比多个线程更快,即使它们本质上具有相同的开销?

C# 使用 DateTime.Now 打入打出

c# - VSTO 加载项部署 - 我可以创建单个文件吗?

c# - BeginInvoke() 是否运行一个单独的线程?

c# - 使用 .Net 中的 IAmsiStream 会导致 AccessViolationException

.net - 可以不编译xaml就部署wpf应用吗?