Pro*_*kov 5 .net c# multithreading threadpool .net-5
我试图弄清楚到底会ThreadPool.SetMinThreads产生什么影响。
根据官方文件说
设置在切换到管理线程创建和销毁的算法之前,当发出新请求时,线程池按需创建的最小线程数。
根据我的理解,作为一名开发人员,我应该能够控制如何按需旋转新线程的机制,因此它们会被创建并在空闲状态下等待,例如在我期望收到请求负载的情况下在特定时间。
这正是我最初认为SetMinThreads方法的设计目的。
但当我开始实际使用它时 - 我得到了非常奇怪的结果。
所以我有我的 ASP.NET .NET5 应用程序,并且在控制器操作中我有如下代码:
ThreadPool.SetMinThreads(32000, 1000);
当然,我直觉地期望运行时为我创建 32K 工作线程和 1000 个 io 线程。
当我这样做,然后调用其他方法 - Process.GetCurrentProcess().Threads获取所有进程的线程,并打印它们的统计信息,我得到这样的东西
Standby - 17
Running - 4
Run Code Online (Sandbox Code Playgroud)
我认为应用程序可能需要一些时间来旋转新线程,所以我尝试了不同的延迟,1 分钟、5 分钟和 10 分钟。
但结果总是保持不变,我得到15-20 Standby和2-4 Running。
那么接下来的逻辑问题是——SetMinThreads方法到底在做什么?MSDN提供的描述似乎没有太大帮助。
还有另一个逻辑问题 - 如果我想强制 dotnet 在空闲状态下旋转 32K 新线程怎么办 - dotnet 是否为此提供了任何机制?
设置按需立即创建的ThreadPool.SetMinThreads最小线程数。这是关键短语,而且确实很不直观。当前\xc2\xb9 (.NET 5) 有两种工作模式:ThreadPoolThreadPool
当新的工作请求到达并且池中的所有线程都忙时,立即创建一个新线程以满足该请求。
\n当新的工作请求到达,并且池中的所有线程都忙时,将请求排队,并在创建新线程之前等待 1 秒,希望在此期间其中一个工作线程能够完成其当前工作,并且将可用于服务排队的请求。
\n设置ThreadPool.SetMinThreads这两种模式之间的阈值。它无法让您控制当前活动的线程数量。这不是很令人满意,但事实就是如此。如果您想强制ThreadPool立即创建 1,000 个线程,除了调用ThreadPool.SetMinThreads(1000, 1000). 像这样的事情应该可以解决问题:
ThreadPool.SetMinThreads(1000, 1000);\nTask[] tasks = Enumerable.Range(0, 1000)\n .Select(_ => Task.Run(() => Thread.Sleep(100)))\n .ToArray();\nRun Code Online (Sandbox Code Playgroud)\n老实说,我认为没有人这样做。创建一个新线程Thread对于人类来说相当快(在我的 PC 中每个线程大约需要 0.25 毫秒),因此对于接收人类请求的系统来说,创建线程的开销应该会产生任何可测量的影响。另一方面,当您希望线程执行少量工作(在纳秒范围内)时,例如在List<T>. 这就是为什么ThreadPool首先发明它的原因:为了分摊微小但大量工作负载的线程创建开销。
请注意,创建新线程Thread也会产生内存成本,这通常比时间成本更重要:每个线程的堆栈至少需要1 MB RAM。因此,创建 32,000 个线程将占用 32 GB 内存,仅用于堆栈空间。这不是很有效。这就是为什么近年来异步编程在服务器端 Web 开发中变得如此重要,因为它允许用更少的线程完成更多的工作。
\xc2\xb9没有什么可以阻止 Microsoft 工程师将来更改/调整其实现ThreadPool。据我所知,这种情况过去至少已经发生过一次。
| 归档时间: |
|
| 查看次数: |
2111 次 |
| 最近记录: |