为啥线程数达到 MinThreads 限制后 ThreadPool.QueueUserWorkItem 很慢? [复制]

Posted

技术标签:

【中文标题】为啥线程数达到 MinThreads 限制后 ThreadPool.QueueUserWorkItem 很慢? [复制]【英文标题】:Why ThreadPool.QueueUserWorkItem is slow after thread count reach the limit of MinThreads? [duplicate]为什么线程数达到 MinThreads 限制后 ThreadPool.QueueUserWorkItem 很慢? [复制] 【发布时间】:2021-07-19 11:05:23 【问题描述】:
class Program
    
        static void DoIt(string name)
                    
            Console.WriteLine($"DateTime.Now, Threadname started");
            Thread.Sleep(50000);
            Console.WriteLine($"DateTime.Now, Threadname done");
        

        static void Main()
        
            //ThreadPool.SetMinThreads(100, 100);

            for (int i = 0; i < 100; i++)
            
                int value = i;
                ThreadPool.QueueUserWorkItem((s) =>
                
                    string name = value.ToString();
                    DoIt(name);
                );
            

            Console.ReadKey();
        
    

程序的结果: result

2021/4/26 11:26:23,线程 2 开始 2021/4/26 11:26:23, Thread0 开始 2021/4/26 11:26:23,线程1开始 2021/4/26 11:26:23,Thread3 开始 2021/4/26 11:26:24,Thread4 启动 2021/4/26 11:26:25,Thread5 启动 2021/4/26 11:26:26,Thread6 启动 2021/4/26 11:26:27,Thread7 启动 2021/4/26 11:26:28,Thread8 启动 2021/4/26 11:26:29,Thread9 开始

同时启动 100 个线程。前 4 个线程非常快。后面的线程每秒启动一个,直到一些工作线程完成。

    为什么前 4 个线程很快? 我电脑的cpu核心数是4。如果程序运行在8核或32核的电脑上,前8或32个线程快,其他慢。 如果 SetMinThreads 为 100,则所有 100 个线程都快速启动

如果我不 SetMinThreads,为什么后面的线程启动这么慢?

【问题讨论】:

GetMaxThreads 返回什么值? 【参考方案1】: .NET 线程池将提供线程,直到达到最小值 (ThreadPool.GetMinThreads),没有任何延迟。 之后,线程池可以等待任务完成(队列)或创建新线程(直到达到 ThreadPool.GetMaxThreads) 没有记录 ThreadPool 何时创建新线程的实际算法,因为它不断发展。但这取决于它运行的硬件和它计算的一堆统计数据。 通过将 SetMinThreads 设置为 100,您实际上是在告诉 .NET 线程池提供 100 个线程,没有任何问题。这就是线程快速启动的原因。 将 MinThreads 设置为较高的值有其自身的缺点 ...(您应该会看到内存使用量增加,因为每个线程都需要有自己的内存用于调用堆栈等,并且当您达到更高数量的线程时,处理器将花更多时间只做上下文切换而不是实际处理) minthreads 的默认值取决于内核数量和 .net 框架版本。这就是为什么当您迁移到不同的硬件时,行为会发生变化。

【讨论】:

本来想说的基本一样。打算为ThreadPool source 添加一个链接,以说明线程池可能很复杂,并且可以解释如何处理最小/最大线程数。

以上是关于为啥线程数达到 MinThreads 限制后 ThreadPool.QueueUserWorkItem 很慢? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

修改linux系统用户最大线程数限制

concurrent模块的使用

线程池参数与线程池调优

为啥 C# 中的多线程不能达到 100% CPU?

Mariadb的多线程连接问题

python 之 进程池与线程池